Ruby - 使用哈希返回数组中的重复项,这是否有效?

时间:2014-05-03 13:35:41

标签: ruby algorithm hash duplicates

我已经使用普通循环解决了这个问题,现在使用哈希,但是我并不自信我使用了哈希以及我可以使用的哈希。这是我的代码:

       # 1-100 whats duplicated

def whats_duplicated?(array)
    temp = Hash.new
    output = Hash.new

    # Write the input array numbers to a hash table and count them
    array.each do |element|
        if temp[element] >= 1
            temp[element] += 1
        else
            temp[element] = 1
        end
    end

    # Another hash, of only the numbers who appeared 2 or more times
    temp.each do |hash, count|
        if count > 1
            output[hash] = count
        end
    end
    # Return our sorted and formatted list as a string for screen
    output.sort.inspect
end

### Main
# array_1 is an array 1-100 with duplicate numbers
array_1 = []
for i in 0..99
    array_1[i] = i+1
end

# seed 10 random indexes which will likely be duplicates
for i in 0..9
    array_1[rand(0..99)] = rand(1..100)
end

# print to screen the duplicated numbers & their count
puts whats_duplicated?(array_1)

我的问题是什么改善?这是我自己的学习练习,我正在练习一些你可能在面试中得到的典型脑筋急转弯,虽然我可以轻松地使用循环,我想学习有效使用哈希。我使用哈希希望提高效率重新解决了这个问题但是查看我的代码我认为它不是最好的。感谢任何对此感兴趣的人!

3 个答案:

答案 0 :(得分:2)

在ruby中查找重复项的最简单方法是对元素进行分组,然后计算每组中的重复数:

def whats_duplicated?(array)
  array.group_by { |x| x }.select { |_, xs| xs.length > 1 }.keys
end

whats_duplicated?([1,2,3,3,4,5,3,2])
# => [2, 3]

答案 1 :(得分:1)

我会这样做:

def duplicates(array)
  counts = Hash.new { |h,k| h[k] = 0 }

  array.each do |number|
    counts[number] += 1
  end

  counts.select { |k,v| v > 1 }.keys
end

array = [1,2,3,4,4,5,6,6,7,8,8,9]

puts duplicates(array)
# => [4,6,8]

有关您的代码的一些评论:块if temp[element] == 1似乎不正确。我认为如果一个数字在数组中出现三次或更多次,那将会失败。你应该至少修改它:

if temp[element]       # check if element exists in hash
  temp[element] += 1   # if it does increment
else
  temp[element] = 1    # otherwise init hash at that position with `1`
end

此外,我建议不要使用for x in foo语法。请改用foo.each do |x|。提示:我想在采访中询问两个版本之间的区别。

答案 2 :(得分:1)

def whats_duplicated?(array)
  array.each_with_object(Hash.new(0)) { |val, hsh| hsh[val] += 1 }.select { |k,v| v > 1 }.keys
end