【问题标题】:How can I remove duplicates in an array without using `uniq`?如何在不使用 `uniq` 的情况下删除数组中的重复项?
【发布时间】:2015-03-05 22:23:25
【问题描述】:

我的编码练习的目的是在不使用uniq 方法的情况下去除数组中的重复项。这是我的代码:

numbers = [1, 4, 2, 4, 3, 1, 5]

def my_uniq(array)
  sorted = array.sort
  count = 1
  while count <= sorted.length
    while true
      sorted.delete_if {|i| i = i + count}
      count += 1
    end
  end
  return sorted
end
  • 当我运行它时,我得到一个无限循环。怎么了?
  • 我可以像使用count 那样使用delete 吗?
  • 它将如何执行?在方法迭代到下一个索引之前,count 会一直持续到数组末尾吗?
  • 我用eachmap 做了这个,得到了相同的结果。使用eachdelete_ifmapwhile 循环(第二个循环与第一个循环比较)的最佳方法是什么?

【问题讨论】:

  • 我不确定你为什么有 2 个 while 循环。内部循环是无限的,因为 while count &lt;= sorted.length 永远不会被查看。
  • 您的问题已得到解答。这是另一种方式:numbers.each_with_object({}) { |n,h| h.update(n=&gt;:anything) }.keys #=&gt;[1, 4, 2, 3, 5] 。这需要 Ruby v1.9+,它将哈希键保持在插入顺序中。它依赖于哈希具有唯一键这一事实。
  • 感谢您的编辑 Cary。我是 SO 新手,正在学习“正确”的提问方式。我会尽量减少措辞;)也感谢您的回答。
  • 您的方法不是最好的,因为数组的大小在变化,但您不断增加索引count。此外,sorted.delete_if {|i| i = i + count} 中的块是指索引,但您可以比较值。
  • 这完全回答了我的一些担忧,但不确定! (我也知道'='应该是'==')。谢谢卡里!

标签: ruby


【解决方案1】:

这是一个写得很清楚的例子。

numbers = [1, 4, 2, 4, 3, 1, 5]

def remove_duplicates(array)
  response = Array.new
  array.each do |number|
     response << number unless response.include?(number)
  end
  return response
end

remove_duplicates(numbers)

【讨论】:

  • 我也喜欢这个答案,因为它符合我的许多尝试之一......但它确实有效!至少我知道我的思考过程是正确的。同样,我很想对此表示赞同,但我还没有代表。感谢您的输入 jBeas,很容易看到正在发生的事情和另一个值得学习的好例子:)
【解决方案2】:

正如其他人指出的那样,您的内部循环是无限的。这是一个没有循环的简洁解决方案:

numbers.group_by{|n| n}.keys

您可以根据需要对其进行排序,但此解决方案不需要它。

【讨论】:

  • 谢谢马克!那是优雅的!我还没有代表(我是菜鸟)来支持你的添加,或者我会;)
【解决方案3】:

问题是内循环是一个无限循环:

while true
  sorted.delete_if {|i| i = i + count}
  count += 1
end #while

你可能可以做你正在做的事情,但它不会消除重复。

一种方法是:

numbers = [1, 4, 2, 4, 3, 1, 5]
target = []
numbers.each {|x| target << x unless target.include?(x) }
puts target.inspect

将其添加到数组类中:

class ::Array
    def my_uniq
       target = []
       self.each {|x| target << x unless target.include?(x) }
       target
    end
end

现在你可以这样做了:

numbers = [1, 4, 2, 4, 3, 1, 5]
numbers.my_uniq

【讨论】:

  • 非常感谢米尔恰!!!由于我将计数设置为仅到 array.length,为什么它是一个无限循环?是计数迭代器的位置吗?我现在正在使用您的解决方案(这很容易理解 - 对此非常感谢),因为它需要成为一种方法,并且还需要添加到 Array 类中。
  • 不。这是真的。这意味着在 true 为 true 时执行,这是永远的
  • 我对它所做的是: numbers = [1, 4, 2, 4, 3, 1, 5] def my_uniq (array) target = [] array.each {|x| target
  • 啊啊啊啊!虽然是真的!我要回去尝试完成这项工作,只是为了嘘!ts和咯咯笑:)
  • 已更新以显示如何将自己的方法添加到数组类:)
【解决方案4】:

你算使用Set,它就像一个不允许重复的数组:

require 'set'
numbers = [1, 4, 2, 4, 3, 1, 5]

Set.new(numbers).to_a
#=> [1, 4, 2, 3, 5]

【讨论】:

  • @seinna 你的意思是“我还没有听说过 Set 类。”
  • 哎呀!确实是jBeas
【解决方案5】:

尝试使用Array#& 将数组本身作为参数传递:

x = [1,2,3,3,3]
x & x #=> [1,2,3]

【讨论】:

    【解决方案6】:

    这是答案之一。但是,我不知道返回唯一性需要多少性能问题

    def my_uniq(ints)
        i = 0
        uniq = []
    
        while i < ints.length
            ints.each do |integers|
                if integers == i
                    uniq.push(integers)
                end
                i += 1
            end
        end
        return uniq
    
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-22
      • 2013-07-31
      • 1970-01-01
      • 2023-03-09
      • 2015-06-14
      相关资源
      最近更新 更多