簡體   English   中英

交換紅寶石哈希中的密鑰

[英]Swap keys in ruby hash

在Ruby中,如何交換哈希中的密鑰?

假設我有以下哈希:

{:one=>1, :two=>2, :three=>3, :four=>4 }

我想轉化為:

{:one=>1, :three=>2, :two=>3, :four=>4}

即,交換鍵:two和:3,但其值保持不變。

最有效的解決方案是什么?

最簡單的方法是:

h = {:one => 1, :two => 2, :three => 3, :four => 4}
h[:two], h[:three] = h[:three], h[:two]

如果您需要定期執行此操作,則可以在Hash上定義一個允許使用更漂亮語法的方法:

class Hash
  def swap!(a, b)
    self[a], self[b] = self[b], self[a] if key?(a) && key?(b)
    self
  end

  def swap(a, b)
    self.dup.swap!(a, b)
  end
end

但請注意,這兩種解決方案都將保留散列中鍵值對的順序。 如果要實際交換密鑰及其值,可以執行以下操作:

class Hash
  def swap(a, b)
    self.inject(Hash.new) do |h, (k,v)|
      if k == a
        h[b] = self[a]
      elsif k == b
        h[a] = self[b]
      else
        h[k] = v
      end
      h
    end
  end
end
{:one => 1, :two => 2, :three => 3, :four => 4}.swap(:two, :three)
# results in {:one=>1, :three=>2, :two=>3, :four=>4}

雖然我不確定您為什么要這么做。

Perl確實很容易做到這一點,但是Ruby沒有哈希切片,因此我們必須以一種更簡單的方式進行:

hash = {:one=>1, :two=>2, :three=>3, :four=>4 }
new_key_order = [:one, :three, :two, :four]

new_hash = Hash[new_key_order.zip(hash.values)]
# => {:one=>1, :three=>2, :two=>3, :four=>4}

之所以可行,是因為Ruby記住了哈希的插入順序,因此values始終按原始順序返回它們。 如果您想在不依賴於廣告訂單的情況下執行此操作,則只需進行一些小改動:

old_key_order = [:one, :two,   :three, :four]
new_key_order = [:one, :three, :two,   :four]

new_hash = Hash[new_key_order.zip(hash.values_at(*old_key_order))]
# => {:one=>1, :three=>2, :two=>3, :four=>4}

注意,我對齊了鍵的列,以使更改真正突出。 當代碼中的某些變化看起來非常相似時,我們將在團隊中這樣做,以使其顯而易見。

可以使用並行分配,但是當您處理許多列或字段時,這確實會很快使混亂的代碼加起來。 像上面那樣定義輸入順序和輸出順序更容易,因此您對映射有非常直觀的參考,然后將它們傳遞給zip並讓它完成艱苦的工作,然后將其強制返回到哈希中。

順便說一句,這就是我在Perl中的做法。 這是使用調試器:

perl -de 1

  DB<1> %hash = ('one' => 1, 'two' => 2, 'three' => 3, 'four' => 4)

  DB<2> x \%hash
0  HASH(0x7fceb94afce8)
   'four' => 4
   'one' => 1
   'three' => 3
   'two' => 2
  DB<3> @hash{'one', 'three', 'two', 'four'} = @hash{'one', 'two', 'three', 'four'}

  DB<4> x \%hash
0  HASH(0x7fceb94afce8)
   'four' => 4
   'one' => 1
   'three' => 2
   'two' => 3

基本上,Perl可以通過將哈希強制轉換為數組並定義鍵的順序來檢索或分配與Ruby的values_at等效的功能。 當你想要重構大量數據時,它是Perl中一個非常強大的工具。

散列中沒有順序概念。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM