2012-11-06 45 views
0

说我有一个这样的数组:如何按照我想要的方式对这个数组进行排序?

[["bham", "php"], 
["auburn", "php"], 
["bham", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["mobile", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["tucson", "php"], 
["tucson", "php"], 
["phoenix", "php"], 
["phoenix", "php"], 
["phoenix", "php"]] 

我希望做的几件事情:

  1. 计算已php作为第二个元素的数组数 - 所以`[“bham “,”php“]将计为1.
  2. 计算每个第一个元素出现在整个列表中的次数。即bham在整个数组中出现了多少次,以及auburn出现了多少次等等。所以基本上,我想循环这个二维数组,并为每个孩子的第一个元素,我想检查看看我是否已经记录了这个字符串 - 如果我有,然后增加记录的值,如果我没有,那么我为这个新的字符串创建一个新的条目。

这个特殊的数组是相对平凡的,可以相对容易地进行视觉化处理,但假设我将拥有一个包含数百/数千个元素的数组。

假设每个子数组的两个元素总是一个单词也是安全的 - 所以它应该相对容易跟踪。

我该如何解决这个问题?

回答

6

计数很简单:

a.count{|x| x[1] == 'php'} 
#=> 24 

而对于分组如何关于group_by:

a.group_by{|x| x[0]}.map{|k,v| [k,v.size]} 
#=> [["bham", 2], ["auburn", 1], ["phoenix", 18], ["mobile", 1], ["tucson", 2]] 
+0

啊,我认为'尺寸'占了一个块,并打算在我的答案中使用它,但后来意识到它没有,但我想只有'数'确实,这就是我想着。 +1 –

+0

我喜欢这个......虽然我有一个问题。你能解释一下'group_by'吗?如同,为什么你先将它们分组(如果你没有将它们分组,那么地图功能是否仍然有效?那么你能解释一下'map'的功能吗?更具体地说,'v.size'如何知道增量?我知道'v'局部变量映射到块中数组的第二个元素。我只是对做'v.size'很感兴趣,因为我完全想做它。 – marcamillion

+0

在irb中尝试一下:'a。GROUP_BY {| X | x [0]} - 它返回一个散列,其中的grouped_by值作为键和匹配数组作为值。 v.size只是应用于匹配数组的数组大小。 – pguardiario

2

计算已PHP作为第二个元素

map让刚刚过去的元素,那么select只有我们关心的是那些阵列的数量,并获得大小:

array.map(&:last).select { |s| s == 'php' }.size 
#=> 24 

统计每个第一个元素出现在整个第Ë列表

map得到公正的第一要素,然后迭代它建立一个哈希存储计数:

array.map(&:first).each_with_object(Hash.new(0)) { |s, h| h[s] += 1 } 
#=> {"bham"=>2, "auburn"=>1, "phoenix"=>18, "mobile"=>1, "tucson"=>2} 
+0

感谢此... I p请参阅pguardiario的解决方案 - 看起来更优雅。但我赞成你的细节和努力。我真的很感谢你花时间:) – marcamillion

相关问题