2012-03-12 24 views
5

mẫu đầu vào:Làm thế nào để nhận được tần số từ theo cách hiệu quả với ruby?

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

và đầu ra:

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

Mã của tôi mà không làm việc:

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

rất liên quan: http://stackoverflow.com/questions/9480852/array-to-hash-words-count – tokland

Trả lời

16

này hoạt động nhưng tôi kinda mới Ruby quá. Có thể có một giải pháp tốt hơn.

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

Thay vì .split(' '), bạn cũng có thể làm .scan(/\w+/); tuy nhiên, .scan(/\w+/) sẽ tách riêng arent trong "aren't", trong khi .split(' ') thì không.

Sản lượng mã ví dụ của bạn:

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

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

Không cần sử dụng 'return', chỉ tần số – megas

+0

Tôi biết nhưng tôi nghĩ rằng việc trả lại giúp bạn dễ dàng hơn để đọc và hiểu. có lẽ vì tôi đến từ java, C++ ... –

+1

Hãy coi chừng: điều này sẽ không hoạt động với các ký tự không phải ASCII, như 'Ł'. –

2

này hoạt động, và bỏ qua những con số:

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

Bạn có thể nhìn vào my code để tách văn bản thành lời nói. Mã cơ bản sẽ trông giống như sau:

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 

Bạn nên cẩn thận nếu bạn muốn làm việc với các ngôn ngữ khác tiếng Anh, vì trong Ruby 1,9 chữ thường sẽ không hoạt động như bạn mong đợi cho các chữ cái như 'Ł' .

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 

đặt "Tôi là 09.809 nhà - Vâng vâng Bạn đã!" .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

Tôi thích cú pháp Hash [] :-) +1 – christianblais

+0

@christianblais Tôi cũng vậy, nhưng tôi cảm thấy mình không cần nó trong trường hợp này. Trong các dự án của tôi, tôi thường thêm 'map_hash' vào' Enumerable', kết hợp với nhau 'map' và' Hash [] '. –

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

biến thể thứ hai:

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

Mã này sẽ yêu cầu bạn cho đầu vào và sau đó tìm tần suất từ ​​cho bạn:

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 
Các vấn đề liên quan