2012-03-12 14 views
5

Numune girişi:Kelime sıklığı ruby ​​ile verimli şekilde nasıl alınır?

"I was 09809 home -- Yes! yes! You was" 

ve çıkışı:

{ 'yes' => 2, 'was' => 2, 'i' => 1, 'home' => 1, 'you' => 1 } 

Kodum çalışmıyor:

def get_words_f(myStr) 
    myStr=myStr.downcase.scan(/\w/).to_s; 
    h = Hash.new(0) 
    myStr.split.each do |w| 
     h[w] += 1 
    end 
    return h.to_a; 
end 

print get_words_f('I was 09809 home -- Yes! yes! You was'); 
+0

çok ilgili: http://stackoverflow.com/questions/9480852/array-to-hash-words-count – tokland

cevap

16

Bu işler ama çok Ruby tür yeniyim. Daha iyi bir çözüm olabilir. Yerine .split(' ') ait

def count_words(string) 
    words = string.split(' ') 
    frequency = Hash.new(0) 
    words.each { |word| frequency[word.downcase] += 1 } 
    return frequency 
end 

, ayrıca .scan(/\w+/) yapabilirdi; Ancak, .scan(/\w+/), ve t'u "aren't"'da ayıramazken, .split(' ') bunu yapmayacaktır. senin örneğin kod

Çıktı:

print count_words('I was 09809 home -- Yes! yes! You was'); 

#{"i"=>1, "was"=>2, "09809"=>1, "home"=>1, "yes"=>2, "you"=>1} 
+0

'Dönüş' kullanmaya gerek yok, sadece – megas

+0

frekansı biliyorum ama dönüşün daha kolay olduğunu düşünüyorum okumak ve anlamak. belki de java'dan geliyorum, C++ ... –

+1

Dikkat: Bu, 'Ł' gibi ASCII olmayan karakterlerle çalışmayacaktır. –

2

Bu işleri ve sayıları sayar: Kelimelerin metin böler my code bakabilirsiniz

def get_words(my_str) 
    my_str = my_str.scan(/\w+/) 
    h = Hash.new(0) 
    my_str.each do |s| 
     s = s.downcase 
     if s !~ /^[0-9]*\.?[0-9]+$/ 
      h[s] += 1 
     end 
    end 
    return h 
end 

print get_words('I was there 1000 !') 
puts '\n' 
2

. olarak görünecektir temel kod aşağıda:

sentence = "Ala ma kota za 5zł i 10$." 
splitter = SRX::Polish::WordSplitter.new(sentence) 
histogram = Hash.new(0) 
splitter.each do |word,type| 
    histogram[word.downcase] += 1 if type == :word 
end 
p histogram 

Eğer mektupları beklendiği gibi downcase böyle 'L' olarak çalışmayacaktır Ruby 1.9 yılında beri İngilizce dışındaki dillerde çalışmak isterseniz dikkatli olmalı .

2
class String 
    def frequency 
    self.scan(/[a-zA-Z]+/).each.with_object(Hash.new(0)) do |word, hash| 
     hash[word.downcase] += 1 
    end 
    end 
end 

"Ben 09.809 ev oldu - Evet evet Sen oldu!" Koyar .frequency

6
def count_words(string) 
    Hash[ 
    string.scan(/[a-zA-Z]+/) 
     .group_by{|word| word.downcase} 
     .map{|word, words|[word, words.size]} 
    ] 
end 

puts count_words 'I was 09809 home -- Yes! yes! You was' 
+0

Hash [] sözdizimini seviyorum :-) +1 – christianblais

+0

@christianblais Ben de yapıyorum ama bu durumda buna ihtiyacım olmamalı gibi hissediyorum. Projelerimde, genellikle 'map' ve 'Hash []' ı bir arada tutan 'map_hash' 'Enumerable''a ekledim. –

6
def count_words(string) 
    string.scan(/\w+/).reduce(Hash.new(0)){|res,w| res[w.downcase]+=1;res} 
end 

İkinci varyant:

def count_words(string) 
    string.scan(/\w+/).each_with_object(Hash.new(0)){|w,h| h[w.downcase]+=1} 
end 
2

Bu kod isteyecektir girdikten sonra sizin için sözcük frekansını bulun:

puts "enter some text man" 
text = gets.chomp 
words = text.split(" ") 
frequencies = Hash.new(0) 
words.each { |word| frequencies[word.downcase] += 1 } 
frequencies = frequencies.sort_by {|a, b| b} 
frequencies.reverse! 
frequencies.each do |word, frequency| 
    puts word + " " + frequency.to_s 
end 
İlgili konular