Как я могу перемешать массив / хэш в Ruby? - PullRequest
9 голосов
/ 21 февраля 2011

В учебных целях, как это называется?Создается ли объект в виде массива или хэша?

stack_of_cards = []

Вот как я его заполняю:

stack_of_cards << Card.new("A", "Spades", 1)
stack_of_cards << Card.new("2", "Spades", 2)
stack_of_cards << Card.new("3", "Spades", 3)
...

Вот мой класс Card:

class Card

  attr_accessor :number, :suit, :value

  def initialize(number, suit, value)
    @number = number
    @suit = suit
    @value = value
  end

  def to_s
    "#{@number} of #{@suit}"
  end
end

Я бы хотел перемешать элементы в этом массиве / хэше (как это называется ?: S)

Есть предложения?

Ответы [ 6 ]

19 голосов
/ 21 февраля 2011
stack_of_cards.shuffle

Это массив, см. http://www.ruby -doc.org / core-1.8.7 / classes / Array.html для получения дополнительной информации.

У меня естьнаписал функциональную форму, которая возвращает новый массив, и это новый, который перемешивается.Вместо этого вы можете использовать:

stack_of_cards.shuffle!

... для перетасовки массива на месте.

10 голосов
/ 17 декабря 2012

Если вы хотите перемешать хеш, вы можете использовать что-то вроде этого:

class Hash
  def shuffle
    Hash[self.to_a.sample(self.length)]
  end

  def shuffle!
    self.replace(self.shuffle)
  end
end

Я отправил этот ответ, так как всегда нахожу этот вопрос, если я ищу "хэш ruby ​​shuffle".

1 голос
/ 17 февраля 2017

Для массивов:

array.shuffle
[1, 3, 2].shuffle
#=> [3, 1, 2]

Для хэшей:

Hash[*hash.to_a.shuffle.flatten]
Hash[*{a: 1, b: 2, c: 3}.to_a.shuffle.flatten(1)]
#=> {:b=>2, :c=>3, :a=>1}
#=> {:c=>3, :a=>1, :b=>2}
#=> {:a=>1, :b=>2, :c=>3}
# Also works for hashes containing arrays
Hash[*{a: [1, 2], b: [2, 3], c: [3, 4]}.to_a.shuffle.flatten(1)]
#=> {:b=>2, :c=>3, :a=>1}
#=> {:c=>[3, 4], :a=>[1, 2], :b=>[2, 3]}
1 голос
/ 31 мая 2013

Если вы хотите сойти с ума и написать свой собственный метод перемешивания на месте, вы можете сделать что-то вроде этого.

 def shuffle_me(array)
   (array.size-1).downto(1) do |i|
     j = rand(i+1)
     array[i], array[j] = array[j], array[i]
   end

   array
 end 
1 голос
/ 21 февраля 2011

В дополнение к с использованием метода shuffle , вы можете использовать метод сортировки:

array.sort {|a, b| rand <=> rand }

Это может быть полезно, если вы используете более старую версию Ruby, где shuffle не реализовано.Как и в случае shuffle!, вы можете использовать sort! для работы с существующим массивом.

0 голосов
/ 18 июля 2018

Если вы хотите перемешать хеш, но не хотите перегружать класс Hash, вы можете использовать функцию сортировки, а затем преобразовать ее обратно в хеш с помощью функции to_h (Ruby 2.1 +):

a = {"a" => 1, "b" => 2, "c" => 3}
puts a.inspect
a = a.sort {|a, b| rand <=> rand }.to_h
puts a.inspect
...