如何根据 Ruby 中 1 的数量创建给定二进制数数组的子数组?

How to create a sub array of given array of binary numbers based on number of 1's in Ruby?

示例:

这里是二进制数组:

a = [001, 010, 100, 011, 101, 110, 111, 1000, 1001, 1010]

我想要如下输出:

[ [ 001, 010, 100, 1000 ], [ 011, 101, 110, 1001, 1010 ], [ 111 ] ]

任何人都可以帮助我如何在 ruby 中实现它吗?

我假设您使用的是字符串 ("001") 而不是 decimal/octal 文字 (001)。如果不是这种情况,我强烈建议转换为字符串以使您更轻松。

我们可以用 x.count('1') 计算字符串 x 中的个数。然后我们可以获取一个字符串列表,并使用 a.group_by(...) 按此值组织它。这给出了一个散列,所以如果您只想要值(如您建议的输出所示),那么您只需获取它的 values

a.group_by { |x| x.count('1') }.values

正如@Silvio 所做的那样,使用 Enumerable#group_by 似乎是解决此问题的最直接方法,但这里有一些其他方法可以使用。

a = "001, 010, 100, 011, 101, 110, 111, 1000, 1001, 1010".split(', ')
  #=> ["001", "010", "100", "011", "101", "110", "111", "1000", "1001", "1010"]

构造一个散列,其键 k 是数字 1,其值是包含原始数组中 one1 等于 k[= 的元素的数组54=]

a.each_with_object({}) { |s,h| (h[s.count('1')] ||= []) << s }.values
  #=> [["001", "010", "100", "1000"], ["011", "101", "110", "1001", "1010"], ["111"]]

values应用于区块返回的哈希,即

{1=>["001", "010", "100", "1000"], 2=>["011", "101", "110", "1001", "1010"], 3=>["111"]}

考虑表达式 (h[s.count('1')] ||= []) << s。让

cnt = s.count('1')

然后 (h[cnt] ||= []) << s 在解析时扩展为以下内容。

(h[cnt] = h[cnt] || []) << s

如果h没有键cnt,那么等式右边的h[cnt]等于nil,所以表达式简化为

(h[cnt] = []) << s

所以h[cnt] #=> [s]。另一方面,如果 h 确实有一个键 cnth[cnt] 等于一个数组,这是真实的,所以我们执行

h[cnt] << s

注意h[cnt] = h[cnt] || []中等式左边的方法是Hash#[]=, whereas we have Hash#[]等式右边的方法

先排序再切片

a.sort_by { |s| s.count('1') }.slice_when { |s1,s2| s1.count('1') < s2.count('1') }.to_a
  #=> [["001", "010", "100", "1000"], ["011", "101", "110", "1001", "1010"], ["111"]]