2012-11-06 90 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

相關問題