简体   繁体   English

比较列表值并从一个列表中删除 - Groovy/Java

[英]Comparing list values and removing from one list - Groovy/Java

I'm writing some tests in groovy using spock where I need to check that the values in two equally sized lists with are correctly mapped to each other and that no duplicate values exist in one of the lists.我正在使用 spock 在 groovy 中编写一些测试,我需要检查两个相同大小的列表中的值是否正确映射到彼此,并且其中一个列表中不存在重复值。 I'm currently doing the following:我目前正在执行以下操作:

I find a given value in list1 then I search for its corresponding value in list2.我在 list1 中找到一个给定值,然后在 list2 中搜索它的对应值。 If I find that corresponding value in list2 I want to remove it.如果我在 list2 中找到相应的值,我想将其删除。 I repeat this to for every position on the list (list1) and at the end I want to verify that list2 is empty.我对列表 (list1) 上的每个 position 重复此操作,最后我想验证 list2 是否为空。 If list2 is not empty at the end it indicates there were some unexpected values or duplicates which were not removed.如果 list2 最后不为空,则表明存在一些未删除的意外值或重复项。

I'm doing the following我正在做以下事情

def list1 = ["a", "b", "c", "d"]
def list2 = ["dog", "goat", "wolf", "fox"]

list1.size() == list2.(size)

list1.size().times() {
 if (list1.contains("a")) {
  if (list2.contains("dog")) {
   println(it + " found dog.... removing")
   list2.remove("dog")
   println(list2)
  }
  if (list1.contains("b")) {
   if (list2.contains("goat")) {
    println(it + " found goat.... removing")
    list2.remove("goat")
    println(list2)
   }
  }
  if (list1.contains("c")) {
   if (list2.contains("wolf")) {
    println(it + " found wolf.... removing")
    list2.remove("wolf")
    println(list2)
   }
  }

  if (list1.contains("d")) {
  if (list2.contains("fox")) {
    println(it + " found fox.... removing")
    list2.remove("fox")
    println(list2)
   }
  }
 }
 }
list2.isEmpty()

This seems to work but im wondering if there is there a more effective way of doing this in groovy?这似乎可行,但我想知道在 groovy 中是否有更有效的方法来做到这一点?

Your approach is very complicated.你的方法很复杂。

The good thing about Spock is, you can split the assertions in multiple parts. Spock 的好处是,您可以将断言拆分为多个部分。

First check for correct mappings.首先检查正确的映射。
And then check for no additional mappings in the remaining lists.然后检查剩余列表中是否没有其他映射。

then: 'correct mapping'
list1.remove("a") == list2.remove("dog")
list1.remove("b") == list2.remove("goat")
list1.remove("c") == list2.remove("wolf")
list1.remove("d") == list2.remove("fox")

and: 'no additional mapping'
list1.isEmpty()
list2.isEmpty()

It is actually even easier than described by Sven, just one line of code if you use the Groovy default method transpose(List) which actually maps to GroovyCollections.transpose(List) :它实际上比 Sven 描述的更简单,如果您使用 Groovy 默认方法transpose(List) ,它实际上映射到GroovyCollections.transpose(List) ,只需一行代码:

package de.scrum_master.stackoverflow.q61859270

import spock.lang.Specification

class ListMappingTest extends Specification {
  static class UnderTest {
    List<String> getFirstList() {
      ["a", "b", "c", "d"]
    }

    List<String> getSecondList() {
      ["dog", "goat", "wolf", "fox"]
    }
  }

  def "lists in matching order"() {
    given:
    def underTest = new UnderTest()
    def list1 = underTest.getFirstList()
    def list2 = underTest.getSecondList()

    expect: "one way to do it: list of lists"
    [list1, list2].transpose() ==
      [["a", "dog"], ["b", "goat"], ["c", "wolf"], ["d", "fox"]]

    and: "another way to do it: map"
    [list1, list2].transpose().collectEntries { [it[0], it[1]] } ==
      [a: "dog", b: "goat", c: "wolf", d: "fox"]
  }

  def "lists in non-matching order"() {
    given:
    def underTest = new UnderTest()
    def list1 = underTest.getFirstList().swap(0, 3)
    def list2 = underTest.getSecondList().swap(1, 2)
    def set1 = list1.toSet()
    def set2 = list2.toSet()

    expect:
    list1.size() == set1.size()
    list2.size() == set2.size()
    set1 == ["a", "b", "c", "d"].toSet()
    set2 == ["dog", "goat", "wolf", "fox"].toSet()
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM