2013-02-14 2 views
1

j'étais curieux de voir comment je factoriser ce code:Comment utiliser lambdas avec des arguments pour collecter un tableau?

array.collect{|x| x.some_method}.inject(:+) || 0 

Je l'ai environ dix fois dans mon code avec des méthodes différentes, donc je pensais que je devrais factoriser, mais comment?

J'ai essayé au moins dix variétés de blocs, procs et lambdas et à ce stade, je ne suis même pas sûr qu'il peut être refactorisé.

+0

Envisager de remplacer les différentes parties avec quelque chose "nommé" tel comme «somme» .. les noms sont bons. Les noms créent une documentation implicite. Si la * même ligne * est répétée plusieurs fois, alors c'est probablement un bon candidat pour "nommer" aussi. –

+0

"refactor" questions de type appartiennent probablement sur http://codereview.stackexchange.com. Voir [la FAQ de CodeReview] (http://codereview.stackexchange.com/faq#questions) pour plus d'informations. –

Répondre

2

Réorganiser comment/quoi? Quel est le but? Voulez-vous/besoin d'aller au-delà:

array.collect(&:some_method).inject(:+) || 0 

Si la seule chose qui change est la méthode appelée, passer le symbole de la méthode dans un procédé et l'envoyer à chaque objet lors de la collecte.

Qu'essayez-vous de communiquer avec le code en question? On dirait une sorte de sommation; peut-être une méthode simple sum avec le nom de "propriété" en tant que paramètre?

+0

+1 pour suggérer l'utilisation d'un nom. Je ne suis pas sûr que je l'ai suivi jusqu'à l'extraction du nom de la propriété, cependant: 'sum people.map (&: age)' ou similaire me semble plutôt bien. –

+0

Le but était de se débarrasser de cette partie du milieu et j'ai enveloppé dans une fonction nommée claire –

0

Vous utilisez array.collect(&:some_method).inject(:+) pour commencer. Vous pouvez aussi le faire avec un inject appel comme ceci:

def my_method(ary, method_symbol) 
    ary.inject (0) do |sum, elem| 
    sum + elem.send(method_symbol) 
    end 
end 
1

Première refactor:

array.collect(&:some_method).inject(0, :+) 

Deuxième refactoring, résumé:

module Enumerable 
    def sum(method) 
    block_given? ? inject(0) { |acc, x| acc + yield(x) } : inject(0, :+) 
    end 
end 

array.map(&:some_method).sum 
array.sum(&:some_method) 
Questions connexes