如何根据 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
确实有一个键 cnt
,h[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"]]
示例:
这里是二进制数组:
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
确实有一个键 cnt
,h[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"]]