Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Ruby: Общие вопросы > Array#uniq |
Автор: valodzka 10.11.2006, 01:43 | ||
Почему неправильно работает этот код?
|
Автор: setq 11.11.2006, 10:08 |
Может быть он использует проверку .equal? ? |
Автор: Pete 11.11.2006, 11:11 | ||
|
Автор: FunnyFalcon 13.11.2006, 13:09 | ||||
Вопрос остаётся открытым!!!
Добавлено @ 13:14 Array вычисляет хэш от аргументов. Hash возвращяет object_id ![]()
|
Автор: Bikutoru 16.11.2006, 12:54 | ||
А как вам такое решение?
Добавлено @ 12:58 Хотя, наверное, проще будет написать свой uniq... |
Автор: FunnyFalcon 16.11.2006, 22:43 | ||
Вариант
|
Автор: Rubynovich 18.11.2006, 14:11 | ||
А вообще, задача немножко бредовая... смущают меня эти пары аля хеш... Уникальность для хешей... странно это все как-то... |
Автор: valodzka 22.11.2006, 18:30 | ||
Если интересно зачем это реализовывалось: программка осуществляет логический вывод по аналогии, результат хранится ввиде хэша {Переменная=>Константа*}, по ходу вывода возникают несколько результатов, но некоторые могут совпадать. Быстро удалить не получилось, пришлось реализовывать свой uniq. Но уже просто интересно стало что за ерунда. |
Автор: Rubynovich 26.11.2006, 22:48 |
valodzka, метод .uniq для хеш -- это носенс. В нем и так все ключи должны быть уникальными. А задача, которую вы решаете, делается методом .update. |
Автор: valodzka 27.11.2006, 14:15 | ||
Непонял... .uniq это для массива хешей, в котором могут содержаться абсолютно одинаковые хэши. И чем здесь мог момочь .update? |
Автор: V.A.KeRneL 10.12.2006, 12:02 | ||||||||||||||||||||||
Спасибо за вариант, FunnyFalcon. Насколько я понял, Вы программист на Python. И в мире Ruby относительный новичок. Посему позволю себе Вас поправить. Ну, во-первых, это как-то странно:
Я понимаю, что переменные `a' и `b' локальные и определены только внутри данного блока кода, да и корректному выполнению метода данное присваивание не помешает, но для меня всё же это сродни присваиванию чего-либо счётчику цикла. Целей для такого присваивания может быть 2: 1) Меньше работать ручками. Тогда Вы мало что выиграли, нужен больший, больший чем 1 строка, кусок кода. 2) Сделать код более читаемым. Это приемлемо. В таком случае, мне кажется, более правильным тут же локально завести новые переменные. Например:
Во-вторых, с учётом 1-го пункта, строку
надо переписать так:
, потому что в Ruby 0 -- это истина, как и всё, кроме false и nil. Ну и последнее, Вы совершенно напрасно использовали метод Array#sort! Тут, очевидно, подразумевался метод Array#sort Метод Array#sort! я вообще практически не использую. Его можно использовать только в том случае, если Вы хотите отсортировать какую-то свою ПЕРЕМЕННУЮ-массив:
И даже тогда лучше это сделать при помощи явного присваивания:
А так все старания по модификации самого объекта тратятся впустую! Добавлено @ 12:15
Оу, FunnyFalcon, а я сначала не заметил, что это тоже Вы написали. И в голову не пришло! ![]() ![]() Единственное, что я здесь не пойму так это:
Отрицательные идентификаторы -- это особенность версии 1.8.5 (у меня 1.8.2 и результаты как у Pete, у него, по-моему, 1.8.4) или сборки под *nix? |
Автор: V.A.KeRneL 11.12.2006, 03:01 | ||
Кстати, FunnyFalcon, зачем в Вашем решении использовалась сортировка, я так и не понял! ![]() Да ещё «аля Python»! ![]() Выстраданное решение:
Добавлено @ 03:13 В тему: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/16778 Еcть идеи насчёт?.. |
Автор: V.A.KeRneL 11.12.2006, 03:45 |
А вообще, о таких интересных вещах неплохо было бы спросить разработчиков... Есть смелые добровольцы с хорошим знанием английского/японского? ![]() |
Автор: FunnyFalcon 11.12.2006, 12:35 | ||||||||||||
Спасибо, вы не правы. Я написал именно то, что хотел: если два ключа сравнимы, то использовать результат их сравнения, иначе (когда a<=>b => nil !!!!), попытаться сравнить их классы, если и классы не сравнимы, то сравнить классы по object_id. В Python любые два объекта сравнимы именно по такому алгоритму, даже если они не связанных друг с другом классов. В Ruby же результат сравнения может быть не определён, если классы сравниваемых объектов отношения друг к другу не имеют.
Метод sort! можно применять к любому объекту-массиву, чье состояние до сортировки вас абсолютно не интересует. В данном случае, массив создается и возвращается методом to_a, поэтому я абсолютно уверен, что этот же объект-массив никто больше не увидит, и я могу отсортировать его на месте, сэкономив память. Впрочем - это дело принципа. Мало ли кто унаследует от Hash и захочет переопределить to_a, чтобы он возвращал кешированное значение. Есть безумцы в этом мире. Если учитывать такую вероятность, то вы абсолютно правы.
Я тоже думал так. Но кто гарантирует, что два хеша с одинаковыми ключами вернут методом to_a массив, в котором ключи будут в одинаковом порядке. Т.е. Вы уверены, что для двух разных объектов - хешей, содержимое которых {1=>2, "2"=>"1"} метод to_a не вернет два разных массива: [[1, 2], ["2", "1"]] и [["2","1"],[1,2]] ? Я не смотрел исходники реализации хэша в Ruby. И кроме того, существуют и другие реализации Ruby (JRuby например). По-этому я не уверен, и подозреваю, что в общем случае to_a может вернуть разные массивы для равных хешей, если история их наполнения и изменения была разной!!! Поэтому я и сортирую массив по первому элементу - ключу в хэше. Но Ruby не позволяет сортировать массив с элементами разных классов - см. выше. По-этому я и сортирую как в Python. |
Автор: Pete 13.12.2006, 00:52 |
Ну, понеслась... А все из-за какого-то простого uniq(). Напомнило тему в разделе Си http://forum.vingrad.ru/index.php?showtopic=37913&view=findpost&p=285338... Добавлено @ 00:53 ![]() |