9

我知道在 Groovy 中,如果

list = [1,2,3,1]

什么时候

list.unique()

有回报

[1,2,3]

但是,如果我想检测列表中重复的非连续项目的重复值。我怎样才能做到这一点?

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

谢谢。

编辑:添加这两种情况

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

true 表示发生任何不连续的重复。

4

5 回答 5

9

这应该这样做:

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

list.countBy{it}.grep{it.value > 1}.collect{it.key}
于 2016-03-10T16:53:44.333 回答
7

如果您需要获取重复元素:

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

    assert nonUniqueElements(['a', 'b', 'b', 'c', 'd', 'c']) == ['b', 'c']
于 2017-06-17T03:26:44.100 回答
6

要确定集合是否包含非唯一项(您的前两个示例),您可以执行以下操作:

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

(注意unique()修改列表)。

同时,Collection.unique()就“分组”项目(您的最后三个示例)而言,似乎按照您的要求进行。

编辑:unique()无论集合是否排序,都可以正常工作。

于 2013-05-30T03:41:27.873 回答
2

您应该能够metaClass列出并添加您自己的detect方法,如下所示:

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
于 2013-05-30T04:44:07.097 回答
1

要知道它是否有重复:

stringList.size() == stringList.toSet().size() // if true, it has no duplicates

要知道哪些值是重复的,您可以执行以下操作:

class ListUtils {

    static List<String> getDuplicates(List<String> completeList) {
        List<String> duplicates = []
        Set<String> nonDuplicates = new HashSet<>()
        for (String string in completeList) {
            boolean addded = nonDuplicates.add(string)
            if (!addded) {
                duplicates << string
            }
        }
        return duplicates
    }

}

这里是它的 Spock 测试用例:

import spock.lang.Specification

class ListUtilsSpec extends Specification {

    def "getDuplicates"() {
        when:
        List<String> duplicates = ListUtils.getDuplicates(["a", "b", "c", "a"])

        then:
        duplicates == ["a"]
    }

}
于 2020-05-11T22:09:02.260 回答