DeleteDuplicates при сохранении структуры подсписка - PullRequest
7 голосов
/ 17 февраля 2012

Я хочу удалить дубликаты из списка списков, сохранив структуру подсписка без изменений.

* 1003 Е.Г. *

{{1, 7, 8}, {4, 3}, {4, 1, 9}, {9, 2}}

становится

{{1, 7, 8}, {4, 3}, {9}, {2}}

Это степень вложенности, и пустые подсписки в порядке.

Ответы [ 3 ]

11 голосов
/ 17 февраля 2012

Это классический трюк:

list = {{1, 7, 8}, {4, 3}, {4, 1, 9}, {9, 2}}

Module[{f},
 f[x_] := (f[x] = Sequence[]; x);
 Map[f, list, {2}]
]

Чтобы понять, как это работает, рассмотрим, что происходит, когда f[1] оценивается впервые.f[1] оценивается как (f[1]=Sequence[]); 1, а затем просто 1.Так что теперь определения были сделаны для f[1].В следующий раз, когда f[1] оценивается, он просто оценивается как Sequence[].

Итак, в первый раз f оценивается для аргумента, он возвращает этот аргумент.Во второй (или третий и т. Д.) Раз он оценивается, возвращается Sequence[].Sequence[] обладает свойством, что он будет полностью удален из выражений, то есть {1, Sequence[], 3} будет иметь значение {1, 3}.

Подводя итог, что функция делает: в первый раз, когда она видит элемент,он заменяет элемент на себя (оставляет его в покое).Во второй раз он видит тот же элемент, он удаляет его.Я отобразил эту функцию на « level 2 », поэтому она будет действовать только на элементы подсписков.

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

Вы можете использовать Complement для этого, и единственное, что вам нужно сделать, это сохранить все элементы, которые вы уже видели. В начале список всех увиденных элементов a пуст, а затем вы постепенно добавляете все числа, которые есть в подсписках. Этот накопленный список используется на каждом этапе для удаления всех чисел, которые уже были просмотрены:

DeleteDuplicatesList[l_List] :=
  Block[{a = {}},
   Table[With[{b = a},
     a = Union[a, c];
     Complement[c, b]], {c, l}]
   ];

l = {{1, 7, 8}, {4, 3}, {4, 1, 9}, {9, 2}};
DeleteDuplicatesList[l]
2 голосов
/ 17 февраля 2012

Это не элегантно, но оно выполняет свою работу:

t = {{1, 7, 8}, {4, 3}, {4, 1, 9}, {9, 2}}; 

Delete[t, Flatten[Rest[Position[t, #]] & /@ (DeleteDuplicates[Flatten[t]]), 1]]

DeleteDuplicates ... вернет множество, а не множество, чисел в t. Rest[Position[ ... вернет позиции дубликатов. Delete удаляет указанные дубликаты.

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