Reputation: 15744
I have Ruby code that looks like this:
a = widgets["results"]["cols"].each_with_index.select do |v, i|
v["type"] == "string"
end
I only want to get the index of any values where v["type"]
is "string". The outer array of "results" has about 10 values (the inner array of "cols" has two -- one of them having an index of "type"); I am expecting two results returned in an array like this: [7, 8]
. But, I am getting results like this:
[[{"element"=>"processed", "type"=>"string"}, 7], [{"element"=>"settled", "type"=>"string"}, 8]]
How can I do this?
Upvotes: 1
Views: 363
Reputation: 33471
If you see cols.each_with_index.to_a
:
[[{:element=>"processed", :type=>"string"}, 0], [{:element=>"processed", :type=>"number"}, 1], ...]
Would give you each hash in an array as the first value, and as the second one, the index. Difficult to get the index if select will return an array that contains all elements of enum for which the given block returns true.
But you also can try with each_index
, which passes the index of the element instead of the element itself, so it would give you just the indexes, like [0,1,2,4]
.
This way you could apply your validation accessing each element in the cols
hash by its index and checking the value for the type
key, like:
widgets = {
results: {
cols: [
{ element: 'processed', type: 'string' },
{ element: 'processed', type: 'number' },
{ element: 'processed', type: 'string' }
]
}
}
cols = widgets[:results][:cols]
result = cols.each_index.select { |index| cols[index][:type] == 'string' }
p result
# [0, 2]
Upvotes: 4
Reputation: 4220
You could use array inject method to get your expected output with minimal #no of lines and the code is something like below,
cols = [{'type' => 'string'}, {'type' => 'not_string'}, {'type' => 'string'}]
cols.each_with_index.inject([]) do |idxs, (v, i)|
idxs << i if v['type'] == 'string'
idxs
end
And the output is like below,
=> [0, 2]
You can change the code as per your need.
Upvotes: 1