2012-02-16 30 views
7

Tôi muốn DeleteDuplicates từ danh sách các danh sách giữ cấu trúc danh sách con còn nguyên vẹn.DeleteDuplicates trong khi giữ lại cấu trúc danh sách con

Ví dụ:

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

trở thành

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

Đây là mức độ làm tổ, và các danh sách con trống là ok.

+0

Chào mừng bạn đến với chồng trao đổi. Nice câu hỏi đầu tiên. Bạn cũng có thể muốn biết về trang web Mathematica (beta): http://mathematica.stackexchange.com/ – DavidC

Trả lời

11

Đây là một thủ thuật cổ điển:

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

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

Để hiểu cách thức hoạt động, xem xét những gì sẽ xảy ra khi f[1] được đánh giá cho lần đầu tiên. f[1] sẽ đánh giá thành (f[1]=Sequence[]); 1, sau đó chỉ cần 1. Vì vậy, bây giờ một định nghĩa đã được thực hiện cho f[1]. Lần sau, f[1] được đánh giá, nó sẽ chỉ đơn giản là đánh giá là Sequence[].

Vì vậy, lần đầu tiên f được đánh giá cho một đối số, nó trả về đối số đó. Thời gian thứ hai (hoặc thứ ba, vv) được đánh giá, nó trả về Sequence[]. Sequence[] có thuộc tính sẽ bị xóa hoàn toàn khỏi các biểu thức, tức là {1, Sequence[], 3} sẽ đánh giá là {1, 3}.

Để tóm tắt, chức năng thực hiện là: lần đầu tiên nó nhìn thấy một phần tử, nó thay thế phần tử với chính nó (để nó một mình). Lần thứ hai nó thấy cùng một phần tử, nó loại bỏ nó. Tôi đã ánh xạ chức năng này tại "level 2", vì vậy nó sẽ chỉ hoạt động trên các phần tử của danh sách con.

+0

Szabolcs, bạn sẽ giải thích nó hoạt động như thế nào? – DavidC

+0

@ Szabolics Cảm ơn, khi tôi cố gắng tấn công điều này, tôi đã gặp một số mã chỉ ra rằng 'Sequence []' có thể hữu ích. Tôi sẽ cố gắng để giải nén này ... bất kỳ ý kiến ​​sư phạm về cách nó hoạt động đánh giá cao! –

+0

+1 để đi [trường học cũ] (http: // stackoverflow.com/a/5248866/618728) –

3

Bạn có thể sử dụng Complement cho điều này và điều duy nhất bạn phải làm là, bạn phải lưu trữ tất cả các phần tử bạn đã xem. Khi bắt đầu danh sách tất cả các phần tử đã xem a trống và sau đó bạn thêm từng bước tất cả các số nằm trong danh sách con. danh sách tích lũy này được sử dụng trong tất cả các bước để xóa tất cả các số đã được nhìn thấy:

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] 
+0

Cảm ơn bạn, tôi thích cách tiếp cận của việc sử dụng 'Complement'. Mặc dù nó không phải là rõ ràng từ cách tôi đã nêu vấn đề ban đầu, có một nền tảng lý thuyết thiết lập cho tất cả điều này. –

2

Nó không phải tao nhã nhưng nó được công việc làm:

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

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

DeleteDuplicates ... sẽ trở lại tập , không phải đa bộ, các số trong t. Rest[Position[ ... sẽ trả về vị trí trùng lặp. Delete xóa các từ khóa trùng lặp.

Các vấn đề liên quan