1

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?

1

2 Answers 2

4

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]
Sign up to request clarification or add additional context in comments.

1 Comment

Note that there are alternatives to using Array#each_index, such as result = cols.size.times.select { ... }, (0...cols.size).select { ... } and 0.upto(cols.size-1).select { ... }.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.