/ / Usando #select su un hash o un array di hash: array, ruby, hash

Usando #select su un hash o un array di hash: array, ruby, hash

I valori nel mio hash sono o un hash annidato:

test_multiple_hash = { test: { another_test: 123 } }

o una serie di hash:

test_multiple_hash = { test: [{ another_test: 123 }, { another_test: 124 }] }

Dopo aver recuperato un valore, ho bisogno di usare #select per trovare hash nidificati specifici:

test_multiple_hash[:test].select { |s| s[:another_test] == 123 }

Se il mio hash ha un solo hash, allora select non soddisfa le mie esigenze a meno che non converta il singolo hash in un array.

C'è un modo migliore per trovare un oggetto in base al valore di una chiave quando il valore di una chiave nell'hash è un singolo hash o un array di hash?

risposte:

1 per risposta № 1

Potresti farlo

[my_hash[:test]].flatten.select { |s| s[:another_test] == 123 }

2 per risposta № 2

Ti suggerisco di iniziare a fare tutti i valori di base del modello comune:

hash = { test: { another_test: 123 },
test2: { test: [{ another_test: 123 }, { another_test: 124 }] }
}

hash.map { |k, v| [k, [*v]] }.to_h # now all of them are arrays.

E poi fai quello che vuoi, assumendo che i valori siano decisamente array, e. g .:

hash.map do |k, v|
[k, [*v]]
end.to_h[:test].select do |s|
s[:another_test] == 123
end

1 per risposta № 3

Il metodo Kernel # Array convertirà il suo argomento in un array:

2.2.1 :002 > Array(1)
=> [1]

a meno che l'argomento non sia già un array; quindi restituisce l'argomento invariato:

2.2.1 :003 > Array([1])
=> [1]

Quindi puoi usare la funzione Array per forzare test_multiple_hash[:test] essere un array:

Array(test_multiple_hash[:test]).select { |s| s[:another_test] == 123 }

Il risultato di #select sarà sempre un array, anche se test_multiple_hash[:test] non era un array.