【问题标题】:Inserting into Set changing the order of Elements in an Array in Ruby在 Ruby 中插入 Set 以改变数组中元素的顺序
【发布时间】:2010-10-05 17:16:36
【问题描述】:
@search_results = Array.new
duplicates = Set.new
results.each { |result|    @search_results.push(result) unless duplicates.add?(result[:url]) }

这段代码弄乱了数组@search_results 中元素的顺序。为什么在集合和数组中插入相同的元素会改变数组的插入顺序?似乎元素引用存在一些问题。谁能解释一下?

编辑 1: 我正在使用一个数组。很抱歉之前的错字。我通过代码进行了双重检查,它也使用了 Array(无论如何都没有 Hash 的推送方法)

【问题讨论】:

  • 变量“results”从何而来?可能是它的顺序是不确定的(例如,如果它是 Hash 或 Set)。
  • 请定义“乱码”:您希望它们按什么顺序排列?订单如何更改?
  • @chuck - 结果是一个数组。 @Lolindrath - 我希望顺序与插入的顺序相同。相反,它给出了一个随机顺序。

标签: ruby arrays set


【解决方案1】:

Hash 中元素的顺序无法保证。如果您想要保证顺序,则必须对键进行排序。

我相信这应该在 Ruby 1.9 中得到修复。

编辑:我假设你的结果是一个数组,如果它是一个哈希,那么顺序就不能保证,你必须对键进行排序,这是我的测试的样子:

#!/usr/bin/ruby -W

require 'pp'
require 'set'

results = Array.new

results << {:url => 'http://lifehacker.com'}
results << {:url => 'http://stackoverflow.com'}
results << {:url => 'http://43folders.com'}
results << {:url => 'http://lolindrath.com'}
results << {:url => 'http://stackoverflow.com'}
results << {:url => 'http://lifehacker.com'}



@search_results = Array.new
duplicates = Set.new

results.each { |result| @search_results.push(result) unless duplicates.add?(result[:url])}

puts "## @search_results"
pp @search_results

如果我运行它,结果如下:

## @search_results
[{:url=>"http://stackoverflow.com"}, {:url=>"http://lifehacker.com"}]

我发现这很奇怪,所以为了确定,我在.add? 末尾添加了一个.nil?,这是我的结果:

## @search_results
[{:url=>"http://lifehacker.com"},
 {:url=>"http://stackoverflow.com"},
 {:url=>"http://43folders.com"},
 {:url=>"http://lolindrath.com"}]

现在是我所期待的:这就是你所说的“乱码”吗?

编辑 2: 经过进一步调查,我认为这是因为 Ruby 在将非布尔数据转换为布尔值时有非常严格的规则(参见 Ruby Gotchas on WikipediaStack Overflow, of course),因此基本上任何只有假是真的假,其他一切都是真的。所以.nil? 将其显式转换为真/假。

irb(main):007:0> puts "zero is true" if 0
zero is true
=> nil
irb(main):008:0> puts "zero is false" unless 0
=> nil

【讨论】:

  • 是的,这正是我的意思。添加 .nil 很奇怪?让它工作。
  • 问题是那个.add?成功时返回 nil,失败时返回对象,因此您正在测试反转条件,因为 nil 在 Ruby 中是错误的
  • 不正确,如果对象已经在集合中,则返回 nil - ruby-doc.org/core/classes/Set.html#M001630
【解决方案2】:

乱码怎么办? results 是什么对象?如果resultsSetHash,则不能保证results 的任何两次遍历都会以相同的顺序。

你也可以

@search_results = results.uniq

如果resultsArray 则获得所有唯一结果。

------------------------------------------------------------- Array#uniq
     array.uniq   -> an_array
------------------------------------------------------------------------
     Returns a new array by removing duplicate values in self.

        a = [ "a", "a", "b", "b", "c" ]
        a.uniq   #=> ["a", "b", "c"]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 2011-12-06
    • 2019-08-02
    相关资源
    最近更新 更多