[英]Sort array of arrays by array value into hash in ruby
I have an array of arrays 我有一个数组数组
[ [1,23,true], [2,33,false],[3,44,true] ]
I'm trying to sort the array based on the [2] value of each inner array, so the outcome would be 我正在尝试根据每个内部数组的[2]值对数组进行排序,因此结果将是
true_values: [ [1,23,true],[3,44,true] ]
false_values: [ [2,33,false] ]
I can select the array objects but am looking for a succinct way of sorting and outputting a hash. 我可以选择数组对象,但是正在寻找一种简洁的排序和输出哈希的方法。
x = [ [1,23,true], [2,33,false],[3,44,true] ]
Since group_by
keeps the order you can sort before you group by: 由于group_by
保持顺序,因此您可以在分组之前先进行排序:
p x.sort_by{|x|x[1]}.group_by(&:last) #=> {true=>[[1, 23, true], [3, 44, true]], false=>[[2, 33, false]]}
and if you do not need to keep the true
/ false
value in the hash: 并且如果您不需要在哈希中保留true
/ false
值:
p x.sort_by{|x|x[1]}.group_by(&:pop) #=> {true=>[[1, 23], [3, 44]], false=>[[2, 33]]}
Here I'm using Enumerable#group_by
to group it by it true or false first, then sorting that hash by the contents of the second element of the array found in v. Lastly we call .to_h
or to hash to get the format you outlined above. 在这里,我首先使用Enumerable#group_by
将其按真或假分组,然后按v中找到的数组的第二个元素的内容对该散列进行排序。最后,我们调用.to_h
或进行散列以获得您概述的格式以上。
[10] pry(main)> arr
=> [[1, 23, true], [2, 33, false], [3, 44, true]]
[11] pry(main)> arr.group_by { |x| x[2] }.sort_by { |_, v| v.map { |i| i[1] } }.to_h
=> {true=>[[1, 23, true], [3, 44, true]], false=>[[2, 33, false]]}
Here's one way: 这是一种方法:
arr = [[1, 44, true], [2, 33, false], [3, 23, true]]
arr.sort_by { |*_,tf| (tf && 0) || 1 }.chunk { |*_,tf| tf }.to_h
#=> {true=>[[1, 44, true], [3, 23, true]], false=>[[2, 33, false]]}
If you want ties broken by, say, arr[i][1]
, then: 如果您希望通过arr[i][1]
打破联系,则:
arr.sort_by { |_,e,tf| [(tf && 0) || 1, e] }.chunk { |*_,tf| tf }.to_h
#=> {true=>[[3, 23, true], [1, 44, true]], false=>[[2, 33, false]]}
Notice that I've changed arr
given in the question to make the second point. 请注意,我已经更改了问题中给出的arr
来说明第二点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.