2013-10-08 11 views
6

Ho due matrici, ciascuno contenente un numero qualsiasi di hash con chiavi identici ma valori differenti:Trova il valore più grande per un array di hash con chiavi comuni?

ArrayA = [{value: "abcd", value_length: 4, type: 0},{value: "abcdefgh", value_length: 8, type: 1}] 
ArrayB = [{value: "ab", value_length: 2, type: 0},{value: "abc", value_length: 3, type: 1}] 

Pur avendo un numero, il numero di hash sarà sempre uguale.

Come è possibile trovare il massimo :value_length per ogni hash il cui valore è di un determinato tipo?

Per esempio, il più grande :value_length per un hash con un :type di 0 sarebbe 4. La più grande :value_length per un hash con un :type di 1 sarebbe 8.

non riesco proprio a ottenere la mia testa intorno questo problema.

risposta

12

Un modo semplice:

all = ArrayA + ArrayB # Add them together if you want to search both arrays. 
all.select{|x| x[:type] == 0} 
    .max_by{|x| x[:value_length]} 

E se si desidera riutilizzarlo solo creare una funzione:

def find_max_of_my_array(arr,type) 
    arr.select{|x| x[:type] == type} 
    .max_by{|x| x[:value_length]} 
end 

p find_max_of_my_array(ArrayA, 0) # => {:value=>"abcd", :value_length=>4, :type=>0} 
+1

Questo mi ha causato così tanti problemi. Soluzione perfetta! (So ​​che non dovresti ringraziare le persone su questo sito, ma questo mi ha davvero aiutato, ed è una risposta concisa e chiara!) – Starkers

+0

Grazie! Risparmia molto tempo. –

0

io non sono del tutto sicuro di sapere che cosa l'uscita che si vuole è, ma prova Questo. Presumo che gli array siano ordinati in modo che ArrayA[x][:type] == ArrayB[x][:type] e che si sta cercando il massimo tra (ArrayA[x], ArrayB[x]) non l'intero array. Se questo non è il caso, allora le altre soluzioni che concatengono prima i due array funzioneranno alla grande.

filtered_by_type = ArrayA.zip(ArrayB).select{|x| x[0][:type] == type } 
filtered_by_type.map {|a| a.max_by {|x| x[:value_length] } } 
0

Ecco come mi sono avvicinato esso: Stai cercando il massimo di qualcosa, così il metodo Array#max sarà probabilmente utile. Vuoi il valore reale stesso, non l'hash che lo contiene, in modo da darci un po 'di flessibilità. Trovarsi a proprio agio con lo stile di programmazione funzionale aiuta qui. Nella mia mente, posso vedere come select, map e max combaciano. Ecco la mia soluzione che, come specificato, restituisce il numero stesso, il valore massimo:

def largest_value_length(type, hashes) 
    # Taking it slowly 
    right_type_hashes = hashes.select{|h| h[:type] == type}             
    value_lengths  = right_type_hashes.map{|h| h[:value_length]}           
    maximum   = value_lengths.max                 

    # Or, in one line              
    #hashes.select{|h| h[:type] == type}.map{|h| h[:value_length]}.max          
end                          

puts largest_value_length(1, ArrayA + ArrayB)                

=> 8 
0

È inoltre possibile ordinare dopo il filtraggio per tipo. In questo modo puoi diventare il più piccolo, il secondo più grande ecc.

all = ArrayA + ArrayB 

all = all.select { |element| element[:type] == 1 } 
     .sort_by { |k| k[:value_length] }.reverse 

puts all[0][:value_length] 
#8 

puts all[all.length-1][:value_length] 
#3 
Problemi correlati