2013-03-07 12 views
13

Benruby: dizideki benzersiz olmayan öğeleri nasıl bulacağınız ve herbiri sayılarla nasıl yazdıracağınız?

a = ["a", "d", "c", "b", "b", "c", "c"] 

varsa ve (olaylar sayısına göre sıralanır azalan) gibi bir şey yazdırmak gerekiyor: (OLMAYAN benzersiz bulma)

c:3 
b:2 

anlıyorum ilk bölümünde geçerli:

b = a.select{ |e| a.count(e) > 1 } 
=> ["c", "b", "b", "c", "c"] 

veya

puts b.select{|e, c| [e, a.count(e)] }.uniq 

c 
b 

Her biri benzersiz olmayan, geriye doğru sıralanan olayların sayısı nasıl çıkarılır?

cevap

19
puts a.uniq. 
     map { | e | [a.count(e), e] }. 
     select { | c, _ | c > 1 }. 
     sort.reverse. 
     map { | c, e | "#{e}:#{c}" } 
+0

Çok zarif! '_' Neyi temsil ediyor? Bunu daha önce hiç görmedim. –

+3

@RichardBrown: Genellikle kullanılmayan anlamına gelen bir değişken adı. – Linuxios

+0

Vay! Teşekkür ederim! – earlyadopter

0

Bu element => occurrences içeren bir karma verecektir:

b.reduce(Hash.new(0)) do |hash, element| 
    hash[element] += 1 
    hash 
end 
+1

daha zarif biraz: 'hash.update (eleman => karma [elemanı] + 1)' –

6

group_by yöntem genellikle bunun için kullanılır:

 
a.group_by{ |i| i } 
{ 
    "a" => [ 
     [0] "a" 
    ], 
    "d" => [ 
     [0] "d" 
    ], 
    "c" => [ 
     [0] "c", 
     [1] "c", 
     [2] "c" 
    ], 
    "b" => [ 
     [0] "b", 
     [1] "b" 
    ] 
} 

Sevdiğim:

 
a.group_by{ |i| i }.each_with_object({}) { |(k,v), h| h[k] = v.size } 
{ 
    "a" => 1, 
    "d" => 1, 
    "c" => 3, 
    "b" => 2 
} 

Ya :

 
Hash[a.group_by{ |i| i }.map{ |k,v| [k, v.size] }] 
{ 
    "a" => 1, 
    "d" => 1, 
    "c" => 3, 
    "b" => 2 
} 

Bunlardan biri kaşıntıyı çizebilir. Ayrıca

 
puts a.group_by{ |i| i }.map{ |k,v| "#{k}: #{v.size}" } 
a: 1 
d: 1 
c: 3 
b: 2 
0
puts a.uniq. 
    map { |e| a.count(e) > 1 ? [e, a.count(e)] : nil }.compact. 
    sort { |a, b| b.last <=> a.last } 
+0

'a & a.uniq'," a "ile aynıdır. –

+2

@undur_gongor Bunun olduğunu sanmıyorum, ama sadece 'a.uniq' olmanın aynısı ... Herhangi bir şekilde, kodumda da değerlerimi yanlış tuttum ve bu da soruyu kötüye kullandı ve düzeltdim. – oldergod

0
a.reduce(Hash.new(0)) { |memo,x| memo[x] += 1; memo } # Frequency count. 
    .select { |_,count| count > 1 } # Choose non-unique items. 
    .sort_by { |x| -x[1] } # Sort by number of occurrences descending. 
# => [["c", 3], ["b", 2]] 

:

a.group_by{|x|x}.map{|k,v|[k,v.size]}.select{|x|x[1]>1}.sort_by{|x|-x[1]} 
# => [["c", 3], ["b", 2]] 
0
sadece bilgi kullanımını yazdırmak isterseniz

 
Hash[a.group_by{ |i| i }.map{ |k,v| v.size > 1 && [k, v.size] }] 
{ 
    "c" => 3, 
    "b" => 2 
} 

: Oradan biraz testi kullanılarak sonucu azaltabilir

Ne dersin:

Ben şahsen bu çözüm gibi
a.sort.chunk{|x| a.count(x)}.sort.reverse.each do |n, v| 
    puts "#{v[0]}:#{n}" if n > 1 
end 
1

:

blok koymak olabilir
a.inject({}) {|hash, val| hash[val] ||= 0; hash[val] += 1; hash}. 
    reject{|key, value| value == 1}.sort.reverse. 
    each_pair{|k,v| puts("#{k}:#{v}")} 
İlgili konular