如何在groovy中找到数组元素的差异?

发布于 2025-01-14 00:28:06 字数 453 浏览 1 评论 0原文

如何找到groovy中映射的数组元素的差异?

def first = [['fruit':'grapes', 'drink':'tea'], 
['fruit':'apple', 'drink':'milk']]

def second = [['fruit':'grapes', 'drink':'tea'], 
['fruit':'melon', 'drink':'milk'],
['fruit':'coconut', 'drink':'soda']]

def diff = first.minus(second)

echo "diff ${diff}

实际输出为

diff []

预期输出为

[['fruit':'melon'],['fruit':'coconut', 'drink':'soda']]

How to find difference of array elements that are maps in groovy?

def first = [['fruit':'grapes', 'drink':'tea'], 
['fruit':'apple', 'drink':'milk']]

def second = [['fruit':'grapes', 'drink':'tea'], 
['fruit':'melon', 'drink':'milk'],
['fruit':'coconut', 'drink':'soda']]

def diff = first.minus(second)

echo "diff ${diff}

Actual output is

diff []

Expected output is

[['fruit':'melon'],['fruit':'coconut', 'drink':'soda']]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

回忆那么伤 2025-01-21 00:28:06

当您想要执行此操作并查找差异时遇到的一个问题是 - 当您比较元素时您优先考虑哪个数组?鉴于您最初的问题,看来您优先考虑较大的一个,因为所需输出中的 fruitmelon (但也可能是 apple )。

考虑到这一点,这是我为您创建的解决方案,它优先考虑更大的数组(您也可以在这里测试它 http: //tpcg.io/03UE84):

def first = [['fruit':'grapes', 'drink':'tea'], 
['fruit':'apple', 'drink':'milk']]

def second = [['fruit':'grapes', 'drink':'tea'], 
['fruit':'melon', 'drink':'milk'],
['fruit':'coconut', 'drink':'soda']]

def diff = []

def biggerArray
def smallerArray

if ( first.size() > second.size() ) {
    biggerArray = first;
    smallerArray = second;
}
else if ( first.size() < second.size() ) {
    biggerArray = second;
    smallerArray = first;
}
else {
    //You have to decide how the diff looks in case they are the same size
}

for ( i = 0; i < biggerArray.size(); i++ ) {
    if ( smallerArray[i] && smallerArray[i] != biggerArray[i] ) {
        def pair = [:]
        if ( smallerArray[i].get("fruit") != biggerArray[i].get("fruit") ) {
            pair["fruit"] = biggerArray[i].get("fruit");
        }
        
        if ( smallerArray[i].get("drink") != biggerArray[i].get("drink") ) {
            pair["drink"] = biggerArray[i].get("drink");
        }
        
        if ( !pair.isEmpty ) {
            diff.add(pair);
        }
    }
    else if ( !smallerArray[i] ) {
        diff.add(biggerArray[i]);
    }
}

println(diff);

One problem you have when you want to do this and find the diff is - which array do you prioritize when you compare the elements? Given your original question, it looks like you prioritize the bigger one as the fruit is melon in your required output (but could've been apple).

Considering this, here is the solution I've created for you which prioritises the bigger array (You can test it here as well http://tpcg.io/03UE84):

def first = [['fruit':'grapes', 'drink':'tea'], 
['fruit':'apple', 'drink':'milk']]

def second = [['fruit':'grapes', 'drink':'tea'], 
['fruit':'melon', 'drink':'milk'],
['fruit':'coconut', 'drink':'soda']]

def diff = []

def biggerArray
def smallerArray

if ( first.size() > second.size() ) {
    biggerArray = first;
    smallerArray = second;
}
else if ( first.size() < second.size() ) {
    biggerArray = second;
    smallerArray = first;
}
else {
    //You have to decide how the diff looks in case they are the same size
}

for ( i = 0; i < biggerArray.size(); i++ ) {
    if ( smallerArray[i] && smallerArray[i] != biggerArray[i] ) {
        def pair = [:]
        if ( smallerArray[i].get("fruit") != biggerArray[i].get("fruit") ) {
            pair["fruit"] = biggerArray[i].get("fruit");
        }
        
        if ( smallerArray[i].get("drink") != biggerArray[i].get("drink") ) {
            pair["drink"] = biggerArray[i].get("drink");
        }
        
        if ( !pair.isEmpty ) {
            diff.add(pair);
        }
    }
    else if ( !smallerArray[i] ) {
        diff.add(biggerArray[i]);
    }
}

println(diff);
冰之心 2025-01-21 00:28:06

因此,我在 groovysh 中尝试了您的代码,并得到了接近您正在寻找的答案的内容:

def first = [['fruit':'grapes', 'drink':'tea'], 
            ['fruit':'apple', 'drink':'milk']]
def second = [['fruit':'grapes', 'drink':'tea'], 
             ['fruit':'melon', 'drink':'milk'],
             ['fruit':'coconut', 'drink':'soda']]
println( first.minus(second) )
println( second.minus(first) )

输出:

 [[fruit:apple, drink:milk]]
 [[fruit:melon, drink:milk], [fruit:coconut, drink:soda]]

minus 方法将依赖于顺序。它不会返回第二个列表中不在第一个列表中的项目。它只会返回第一个列表中的项目。因此“melon”、“coconut”不会与 first.minus(second) 一起出现。当然,明显的问题是 drink: milk 出现,因为它包含在地图中,其中 1 个成员不在第一个地图中,因此它包含该地图的所有成员。这就是 minus 方法的工作原理,因此它不能成为解决方案。

因此,这是另一种方法,可以满足您的期望(但它仍然依赖于顺序):

def first = [['fruit':'grapes', 'drink':'tea'],
             ['fruit':'apple', 'drink':'milk']]
def second = [['fruit':'grapes', 'drink':'tea'],
              ['fruit':'melon', 'drink':'milk'],
              ['fruit':'coconut', 'drink':'soda']]

def diff( srcA, srcB ) {
    srcA.findResults { item ->
       def out = item.findAll { x ->
         !srcB.find { y -> y.containsKey(x.key) && y[x.key] == x.value }
       }
       out ?: null
    }
}

println( "first diff second = ${diff( first, second )}" )
println( "second diff first = ${diff( second, first )}" )

输出:

first diff second = [[fruit:apple]]
second diff first = [[fruit:melon], [fruit:coconut, drink:soda]]

So I tried your code in groovysh and got something close to the answer you were looking for:

def first = [['fruit':'grapes', 'drink':'tea'], 
            ['fruit':'apple', 'drink':'milk']]
def second = [['fruit':'grapes', 'drink':'tea'], 
             ['fruit':'melon', 'drink':'milk'],
             ['fruit':'coconut', 'drink':'soda']]
println( first.minus(second) )
println( second.minus(first) )

Output:

 [[fruit:apple, drink:milk]]
 [[fruit:melon, drink:milk], [fruit:coconut, drink:soda]]

The minus method is going to be order dependent. It won't return items in the second list that aren't in the first. It's only going to return the items that are only in the first list. So 'melon', 'coconut' aren't going to show up with first.minus(second). Of course the obvious issue is that drink: milk shows up because it is contained within maps where 1 member isn't in the first so it includes all members of that map. That's just how minus method works so it can't be a solution.

So here is another method that does what you expect (but it's still order dependent):

def first = [['fruit':'grapes', 'drink':'tea'],
             ['fruit':'apple', 'drink':'milk']]
def second = [['fruit':'grapes', 'drink':'tea'],
              ['fruit':'melon', 'drink':'milk'],
              ['fruit':'coconut', 'drink':'soda']]

def diff( srcA, srcB ) {
    srcA.findResults { item ->
       def out = item.findAll { x ->
         !srcB.find { y -> y.containsKey(x.key) && y[x.key] == x.value }
       }
       out ?: null
    }
}

println( "first diff second = ${diff( first, second )}" )
println( "second diff first = ${diff( second, first )}" )

Output:

first diff second = [[fruit:apple]]
second diff first = [[fruit:melon], [fruit:coconut, drink:soda]]
霊感 2025-01-21 00:28:06

这对我来说有效,

def first = [['fruit':'grapes', 'drink':'tea'], ['fruit':'apple', 'drink':'milk']] 
def second = [['fruit':'grapes','drink':'tea'],
['fruit':'melon', 'drink':'milk'], ['fruit':'coconut', 'drink':'soda']]

def firstDiff = first.findAll { !second.contains(it) }
def secondDiff = second.findAll { !first.contains(it) }

println(firstDiff);
println(secondDiff);

输出:

['fruit':'apple', 'drink':'milk']
[['fruit':'melon', 'drink':'milk'],['fruit':'coconut', 'drink':'soda']]

This works on my end,

def first = [['fruit':'grapes', 'drink':'tea'], ['fruit':'apple', 'drink':'milk']] 
def second = [['fruit':'grapes','drink':'tea'],
['fruit':'melon', 'drink':'milk'], ['fruit':'coconut', 'drink':'soda']]

def firstDiff = first.findAll { !second.contains(it) }
def secondDiff = second.findAll { !first.contains(it) }

println(firstDiff);
println(secondDiff);

The output:

['fruit':'apple', 'drink':'milk']
[['fruit':'melon', 'drink':'milk'],['fruit':'coconut', 'drink':'soda']]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文