2010-11-21 5 views
2

J'ai un tableau de activerecordproblème de méthode Ruby Injecter

[#<Lead id: 134, address: "24 elm33",created_at: "2010-11-15 12:08:25", updated_at: "2010-11-16 12:53:36", usd_conv: 2741>, 
#<Lead id: 136, address: "guigiu", created_at: "2010-11-17 16:57:45", updated_at: "2010-11-17 16:57:45", usd_conv: 1000>] 

et je veux changer cela en utilisant injectent à [[created_at, usd_conv (chiffre total pour ce moment-là)]]

Tous les assistants là-bas savoir comment faire cela?

+0

Soyez plus précis. Vous voulez obtenir une somme, une séquence de sommes partielles? – samuil

+0

désolé, pour clarifier, je cherche la séquence des sommes partielles. Ainsi, à partir de l'exemple ci-dessus, j'aurais [[2010-11-15 12:08:25, 2741], [2010-11-17 16:57:45, 3741]]. Merci encore les gars – stuartchaney

+0

okay, j'ai corrigé ma réponse –

Répondre

3

En supposant que vous avez besoin « pour chaque fois created_at séparé, calculer la somme totale de tous usd_conv jusqu'à ce jour », cela se fait en injectant des valeurs un par un dans une structure de données. Voici un exemple qui « injecte » enregistre dans un tableau à deux valeurs:

  • le premier élément accumule enregistrements résultants
  • le second accumule la somme pour un moment en cours

    array.inject([0,[]]) do |so_far,elem| 
        so_far[0] += elem.usd_conv 
        so_far[1] << [elem.created_at, so_far[0]] 
        so_far # Necessary because block should return the next so_far 
    end 
    
+0

Peut-être que je me trompe, mais je suppose que created_at a une résolution si dense, que vous obtiendrez hash avec nombre d'éléments égal nombre d'enregistrements originaux ... – samuil

+0

cheers pavel. c'est tout, sauf le total apparaissant au départ. Merci encore. – stuartchaney

0
array.collect!{|e| [e.created_at, e.usd_conv]} 
+0

merci pour votre réponse Eimantas :), mais j'ai peur je cherche le total de usd_conv. Je pense que injecter est la bonne voie à suivre mais je ne sais pas si bien .. – stuartchaney

0

Il n'est pas une application typique de la méthode inject (reduce). L'idée est de l'utiliser pendant que vous réduisez le tableau en valeur unique. L'utilisation de inject sur d'autres itérateurs vous permet ici de ne pas définir de variable locale explicitement (ce qui est bien, si vous avez une approche fonctionnelle). Qu'est-ce que vous avez vraiment besoin est une combinaison de map et inject - utilisation du tableau de valeurs passées dans l'accumulateur est à mon avis de vacherie;)

Comme il n'y a pas de méthode spécifique pour faire de telles choses que je tiendrais à map (ou map!) :

accumulator = 0 
ary.map! {|el| [el.created_at, accumulator += el.usd_conv]} 

La partie inférieure encombre la portée de niveau supérieur avec l'accumulateur.

La version utilisant map semble être 2 à 3 fois plus rapide lorsqu'elle est comparée (map vs map! version).