Home > Blockchain >  Counting duplicates in ruby array and storing count in hash
Counting duplicates in ruby array and storing count in hash

Time:10-01

I have a dictionary of words and I want to check if a given string has any of those words. I want them to be stored in a hash with the key being the repeated word, and the value being how many times it occurred.

Currently, it only will store complete string matches (below is not counted as containing the word low) and does not actually increase the counter of duplicates.

Point me in the right direction? :)

dictionary = ["below","down","go","going","horn","how","howdy","it","i","low","own","part","partner","sit"]

def substringer(string, dict)
  string_array = string.split(/\W /)
  final_hash = {}
  count = 0
  dict.each do |entry|
    if string_array.include?(entry)
      final_hash = {entry =>  1}
      p final_hash
    end
  end
end

substringer("below, below, how's it goin?", dictionary)

result

{"below"=>1}
{"how"=>1}
{"it"=>1}

CodePudding user response:

here's my "one-liner" solution:

dictionary = ["below", "down", "go", "going", "horn", "how", "howdy", "it", "i", "low", "own", "part", "partner", "sit"]

str = "below, below, how's it goin?"

str.split(/\W /).tally.slice(*dictionary) #=> {"below"=>2, "how"=>1, "it"=>1}

CodePudding user response:

string_array.include?(entry) returns true, regardless of how many times the word occurs in given array. Instead, use string_array.count(entry) which will tell you exactly how many times it appears.

dict.each do |entry|
  count = string_array.count(entry)
  final_hash[entry] = count if count > 0
end

However, it is not the most efficient way - as you need to iterate through string_array once per each dictionary word (and I'd assume that string_array is potentially much larger than dictionary). Try thinking of a way of iterating over string array instead.

Also, consider what to do about words starting with capital letters!

CodePudding user response:

Let's invert your code and loop over elements in string_array and check for inclusion in dict.

Also using #each_with_object to build up the hash, and Hash.new(0) creates a hash where the default value for a key is 0.

dictionary = ["below", "down", "go", "going", "horn", "how", "howdy", "it", "i", "low", "own", "part", "partner", "sit"]

def substringer(string, dict)
  string_array = string.split(/\W /)

  final_hash = string_array.each_with_object(Hash.new(0)) do |word, hsh|
    hsh[word]  = 1 if dict.include?(word)
  end

  p final_hash
end

Testing this:

substringer("below, below, how's it goin?", dictionary)
# {"below"=>2, "how"=>1, "it"=>1}
  •  Tags:  
  • ruby
  • Related