2009-02-05 50 views
0
@search_results = Array.new 
duplicates = Set.new 
results.each { |result| @search_results.push(result) unless duplicates.add?(result[:url]) } 

這段代碼正在琢磨數組@search_results中元素的順序。爲什麼在集合和數組中插入相同的元素會改變Array的插入順序?看起來像元素引用的一些問題。有人可以解釋嗎?我正在使用數組。我使用數組。對不起,以前的錯字。我再次檢查代碼,它也使用陣列(無論如何不存在推送方法)插入設置更改紅寶石中數組中元素的順序

+0

變量「結果」來自哪裏?它的順序可能是不確定的(例如,如果它是哈希或集合)。 – Chuck 2009-02-05 23:48:12

+0

請定義'亂碼':你期望它們在什麼順序?訂單如何變化? – Lolindrath 2009-02-06 12:56:05

+0

@chuck - 結果是一個數組。 @Lolindrath - 我期望的順序與它插入的順序相同。相反,它給出了一個隨機順序。 – Sanjay 2009-02-06 13:13:14

回答

2

散列中元素的順序不能保證。如果您需要保證訂單,則必須對密鑰進行排序。

我認爲這應該在Ruby 1.9中修復。

編輯:我假設數組中的搜索結果,如果一個Hash然後順序不能保證,你將不得不鍵排序,這裏是我的測試是什麼樣子:

#!/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"}] 

我發現奇怪的,所以只是可以肯定,我把.nil?.add?結束,這裏是我的結果:

## @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?顯式轉換爲true/false。

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 
0

亂碼怎麼樣?什麼樣的對象是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"]