1

So i have a multidimensional array in ruby which looks like this

[["34224", "1"],["20561", "1"],["26195", "1"],["32098", "1"],
 ["33375", "1"],["34077", "1"],["34219", "1"],["34220", "1"],
 ["34223", "1"],["19178", "1"],["33650", "1"],["33654", "1"],
 ["33715", "1"],["33716", "1"],["33966", "1"],["33967", "1"],
 ["33968", "1"],["34068", "1"],["34069", "1"],["34070", "1"],
 ["34071", "1"],["34072", "1"],["34073", "1"],["34074", "1"],
 ["34075", "1"],["34076", "1"],["33515", "2"],["33717", "2"],
 ["33852", "2"],["33965", "2"],["34222", "2"]]

Basically, the second value in each array is the count.

I wiant to get all the values in the array where the count is 1 and where the count is 2. I want to be able to sort them apart.

How do i do tht in the cleanest ruby way possible

2
  • There are no multi-dimensional arrays in Ruby (unless you count Matrix from the standard library), what you have is an array whose elements are arrays but a multi-dimensional array is quite a different beast. Commented Dec 16, 2016 at 1:43
  • Since this is tagged with "ruby-on-rails" – is that array the result of a database query? If so, please show the query, maybe the database can handle the grouping more efficiently. Commented Dec 16, 2016 at 8:36

4 Answers 4

1

You're not talking about "sorting", you're talking about creating subsets. In the easiest way, you can use the last method of an array to get the last value. Here's what it looks like:

arr.select { |item| item.last == '1' }
arr.select { |item| item.last == '2' }
Sign up to request clarification or add additional context in comments.

Comments

1

You should be using group_by:

array.group_by{|a| a.last}

1 Comment

I think array.group_by(&:last) - looks more pretty :)
0

If you want to first group them by the second element of each array and then sort each group based on first element, you can do it like this:

array = [["34224", "1"], ["20561", "1"], ["26195", "1"], ["32098", "1"], ["33375", "1"], ["34077", "1"], ["34219", "1"], ["34220", "1"], ["34223", "1"], ["19178", "1"], ["33650", "1"], ["33654", "1"], ["33715", "1"], ["33716", "1"], ["33966", "1"], ["33967", "1"], ["33968", "1"], ["34068", "1"], ["34069", "1"], ["34070", "1"], ["34071", "1"], ["34072", "1"], ["34073", "1"], ["34074", "1"], ["34075", "1"], ["34076", "1"], ["33515", "2"], ["33717", "2"], ["33852", "2"], ["33965", "2"], ["34222", "2"]]
hash = array.group_by { |e| e[1] }
hash.keys.each do |key|
  hash[key] = hash[key].sort_by { |e| e[0].to_i }
end
hash  # Final result

This is based on assumption that both your first and second elements of the array will be number represented as strings.

Comments

0

Using group_by, sort and map :

ids_and_count = [
 ["34224", "1"],["20561", "1"],["26195", "1"],["32098", "1"],
 ["33375", "1"],["34077", "1"],["34219", "1"],["34220", "1"],
 ["34223", "1"],["19178", "1"],["33650", "1"],["33654", "1"],
 ["33715", "1"],["33716", "1"],["33966", "1"],["33967", "1"],
 ["33968", "1"],["34068", "1"],["34069", "1"],["34070", "1"],
 ["34071", "1"],["34072", "1"],["34073", "1"],["34074", "1"],
 ["34075", "1"],["34076", "1"],["33515", "2"],["33717", "2"],
 ["33852", "2"],["33965", "2"],["34222", "2"]]

ids_by_count = ids_and_count.group_by { |_, count| count }.map { |count, ids_and_count_by_count|
  [
    count.to_i,
    ids_and_count_by_count.map { |id, _| id.to_i }.sort
  ]
}.to_h

ids_by_count is now :

{
    1 => [
        19178,
        20561,
        26195,
        32098,
        33375,
        33650,
        33654,
        33715,
        33716,
        33966,
        33967,
        33968,
        34068,
        34069,
        34070,
        34071,
        34072,
        34073,
        34074,
        34075,
        34076,
        34077,
        34219,
        34220,
        34223,
        34224
    ],
    2 => [
        33515,
        33717,
        33852,
        33965,
        34222
    ]
}

If you want all the ids that appear twice :

ids_by_count[2] # => [33515, 33717, 33852, 33965, 34222]

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.