Осуществление проверки равенства в UNIQUE и других операций набора, как представляется, Cmp_Value
, и способ сравнения делается, чтобы вычесть кадров указатели объектов. Если это вычитание равно нулю (например, это тот же самый объект?), То сравнение считается матч:
f-series.c Line 283, R3-Alpha open source release
Если вы посмотрите на окружающий код, который вы увидите вызов Cmp_Block в той же процедуре , В случае Cmp_Block это делает рекурсивное сравнение, и чтит чувствительность к регистру ... поэтому разница между тем, как блоки и объекты действуют:
Cmp_Block() in f-series.c
Учитывая, что написано, что путь, если вы хотите, UNIQUE-операция, основанная на сравнении полей между объектами и их идентичностью, нет возможности сделать это, помимо написания вашей собственной процедуры и вызова EQUAL? ... или изменения кода C.
Вот короткий взлом, не требующий изменения источника C, который делает MAP-EACH на выходе UNIQUE. Тело отфильтровывает любой EQUAL? объекты, которые уже были замечены (потому что, когда тело МАР-КАЖДОЙ возвращаются неустановленной, он ничего не добавляет к результату):
my-unique: function [array [block!]] [
objs: copy []
map-each item unique array [
if object? :item [
foreach obj objs [
if equal? item obj [unset 'item break]
]
unless unset? :item [append objs item]
]
:item ;-- if unset, map-each adds nothing to result
]
]
К сожалению, вы должны использовать BLOCK! а не MAP! отслеживать объекты, как вы идете, потому что MAP! в настоящее время не разрешает объекты как ключи. Если бы они допустили это, у них, вероятно, была бы такая же проблема, что и объекты с равными равными единицами хэширования.
. (Примечание: Фиксация это и другие вопросы на радаре ветви Рен-C, который, в дополнение к в настоящее время самый быстрый Rebol интерпретатор с fundamental fixes, также имеет немного enhancements to the set operations обсуждения в chat)
Просто хотел добавить примечание, что это только R3, но там отлично работает. Спасибо за ответ! –