Сортировка хеш-таблицы объектов (по атрибутам объектов) в Ruby - PullRequest
0 голосов
/ 02 февраля 2012

Скажем, у меня есть класс с именем Person, и он содержит такие вещи, как фамилия, имя, адрес и т. Д.

У меня также есть хэш-таблица объектов Person, которые необходимо отсортировать по последним иимя.Я понимаю, что sort_by не будет постоянно менять хеш, что нормально, мне нужно печатать только в таком порядке.В настоящее время я пытаюсь выполнить сортировку / печать на месте с помощью:

@hash.sort_by {|a,b| a <=> b}.each { |person| puts person.last}

Я перегружен оператором <=> для сортировки по последнему / первому, но на самом деле ничего не сортируется.Положения туда просто выводят в оригинальном порядке хэша.Я потратил хорошие 4 дня, пытаясь это выяснить (это школьное задание и моя первая программа Ruby).Есть идеи?Я уверен, что это легко, но мне очень трудно вывести свой мозг из мышления C ++.

Ответы [ 3 ]

4 голосов
/ 02 февраля 2012

Вы, кажется, сбиваете с толку sort и sort_by

sort возвращает два объекта из коллекции в блок и ожидает, что вы вернете <=> подобное значение: -1,0 или 1 в зависимости от того, равны ли аргументы, по возрастанию или по убыванию, например

%w(one two three four five).sort {|a,b| a.length <=> b.length}

Сортирует строки по длине. Это форма для использования, если вы хотите использовать свой оператор <=>

sort_by возвращает по одному объекту из коллекции за раз и ожидает, что вы вернете то, что вы хотите отсортировать, - вам не следует здесь сравнивать. Затем Ruby использует <=> в этих объектах для сортировки вашей коллекции. Предыдущий пример может быть переписан как

%w(one two three four five).sort_by {|s| s.length}

Это также известно как преобразование Шварца

В вашем случае коллекция представляет собой хэш, поэтому все немного сложнее: значения, которые передаются в блок, являются массивами, которые содержат пары ключ / значение, поэтому вам необходимо извлечь объект person из этой пары. Вы также можете просто работать с @ hash.keys или @ hash.values ​​(в зависимости от того, являются ли объекты person ключами или значениями)

3 голосов
/ 02 февраля 2012

Если вы переопределили оператор <=> для правильной сортировки объектов Person, то вы можете просто сделать:

@hash.sort_by{ |key, person| person }

потому что sort_by будет выдавать как хеш-ключ, так и объект (в вашем случае человек) для каждой итерации блока. Таким образом, приведенный выше код отсортирует ваш хеш на основе объектов Person, для которых вы уже указали оператор <=>.

0 голосов
/ 02 февраля 2012

Когда вы #.sort_by используете хэш, параметры, передаваемые в блок, представляют собой «ключ», «значение», а не «элемент a» и «элемент b».Попробуйте:

@hash.sort_by{|key,value| value.last}.each{|key,value| puts value.last}

Также см. Превосходное объяснение Фредерика Ченга о #sort против #sort_by.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...