2013-05-30 21 views
6

Tôi biết rằng trong Groovy, nếuGroovy: cách đơn giản nhất để phát hiện giá trị nhân bản, không liên tiếp trong một danh sách

list = [1,2,3,1] 

khi

list.unique() 

với lợi nhuận

[1,2,3] 

Nhưng nếu tôi muốn phát hiện giá trị trùng lặp cho các mục trùng lặp, không liên tiếp trong một danh sách. Tôi có thể làm cái này như thế nào?

detect([1,2,3,1]) => true 
detect([1,2,3,2]) => true 
detect([1,1,2,3]) => false 
detect([1,2,2,3,3]) => false 
detect([1,2,3,4]) => false 

Cảm ơn.

Edit: thêm hai trường hợp, những

detect([1,2,2,1]) => true 
detect([1,2,1,1]) => true 

đúng nghĩa là bất kỳ không liên tiếp, lặp lại xảy ra.

Trả lời

2

Bạn sẽ có thể vào danh sách metaClass và thêm phương pháp detect riêng của bạn như sau:

List.metaClass.detect = { 
    def rslt = delegate.inject([]){ ret, elem -> 
     ret << (ret && ret.last() != elem ? elem : !ret ? elem : 'Dup') 
    } 
    return (!rslt.contains('Dup') && rslt != rslt.unique(false)) 
} 

assert [1,2,3,1].detect() == true //Non-consecutive Dups 1 
assert [1,2,3,2].detect() == true //Non-consecutive Dups 2 
assert [1,1,2,3].detect() == false //Consecutive Dups 1 
assert [1,2,2,3,3].detect() == false //Consecutive Dups 2 and 3 
assert [1,2,3,4].detect() == false //Unique no dups 
+0

Rất tuyệt! Tôi chỉ muốn biết cách thực hiện '! Ref' có nghĩa là danh sách trống trong mã của bạn? –

+1

Có chính xác. Tôi có thể thử tối ưu hóa việc triển khai metaClass nhiều hơn nếu nó có thể có nhiều rãnh hơn. – dmahapatro

+0

oops, '[1,2,2,1] .detect()' và '[1,2,1,1] .detect()' trả về false, nhưng tôi nghĩ rằng nó phải đúng. Tôi nhớ hai trường hợp này khi tôi xác định câu hỏi. –

5

Để xác định xem một bộ sưu tập bao gồm các mặt hàng không duy nhất (hai ví dụ đầu tiên của bạn), bạn có thể làm một cái gì đó như thế này:

def a = [1, 2, 3, 1] 
boolean nonUnique = a.clone().unique().size() != a.size() 

(Lưu ý rằng unique() đổi danh sách).

Trong khi đó, Collection.unique() có vẻ như làm những gì bạn đã yêu cầu như các mục 'nhóm' (ba ví dụ cuối cùng của bạn).

Chỉnh sửa: unique() hoạt động bình thường bất kể bộ sưu tập có được sắp xếp hay không.

+0

Cảm ơn! Nhưng phương pháp này không thể phát hiện sự liên tiếp của mục danh sách, phải không? –

+0

Không, nó không thể - nó không rõ ràng rằng đó là những gì bạn đang yêu cầu. – GreyBeardedGeek

2

này nên làm điều đó:

List list = ["a", "b", "c", "a", "d", "c", "a"] 

list.countBy{it}.grep{it.value > 1}.collect{it.key} 
0

Trong trường hợp bạn cần lấy các phần tử trùng lặp:

def nonUniqueElements = {list -> 
     list.findAll{a -> list.findAll{b -> b == a}.size() > 1}.unique() 
    } 

    assert nonUniqueElements(['a', 'b', 'b', 'c', 'd', 'c']) == ['b', 'c'] 
Các vấn đề liên quan