how to compare to collections of map in groovy

71 Views Asked by At
def m = [
    [id: 7144, name: "Test załącznika.docx", group: "3#Gotowe do akceptacji"],
    [id: 7145, name: "Test załącznika 2.docx", group: "3#Gotowe do akceptacji"],
    [id: 7146, name: "Test integracji dział prawny cd..docx", group: "3#Gotowe do akceptacji"],
    [id: 7147, name: "Test załącznika 3.docx", group: "3#Gotowe do akceptacji"],
    [id: 7153, name: "Z.8.DRWS.P.01.F.01.PL.01 Wykaz dokumentów związanych i załączników.docx", group: "3#Gotowe do akceptacji"]
]

def mj = [
    [id: 24930, name: "Test integracji dział prawny cd. nowy.docx"],
    [id: 24931, name: "Test załącznika nowy.docx"],
    [id: 24932, name: "Test załącznika 3 nowa.docx"],
    [id: 23432, name: "xoxoxoxx.docx"],
    [id: 24933, name: "Test załącznika 2 nowy.docx"]
]

m.each { webcFile ->
    def webcName = webcFile.name
    def webcGroup = webcFile.group

    def webcNameWithoutExtension = webcName.take(webcName.lastIndexOf('.'))

    mj.each { jiraFile ->
        def jiraName = jiraFile.name
        def jiraNameWithoutExtension = jiraName.take(jiraName.lastIndexOf('.'))
        if (jiraNameWithoutExtension.contains(webcNameWithoutExtension) && webcGroup == "3#Gotowe do akceptacji") {

        } else if (!jiraNameWithoutExtension.contains(webcNameWithoutExtension)) {

           println(jiraNameWithoutExtension)


    }
}
}

I have to compare two collection of map and print if value from first of map contains value from second or dont.

if statement works fine but else if dont. it should print only xoxoxoxx but prints

Test integracji dział prawny cd. nowy
xoxoxoxx
Test integracji dział prawny cd. nowy
Test załącznika nowy
Test załącznika 3 nowa
xoxoxoxx
Test załącznika nowy
Test załącznika 3 nowa
xoxoxoxx
Test załącznika 2 nowy
Test integracji dział prawny cd. nowy
Test załącznika nowy
xoxoxoxx
Test załącznika 2 nowy
Test integracji dział prawny cd. nowy
Test załącznika nowy
Test załącznika 3 nowa
xoxoxoxx
Test załącznika 2 nowy

from script point of view everything is correct but prints to much. Could you help me a little?

2

There are 2 best solutions below

0
cfrick On

First of all, I think part of the problem is, that all the file names from mj are all post-fixed with now[ya] so there actually are no duplicated with the rules you put in play here.

Next each can not (really) short-circuit, so with two nested each you will pay for some useless work and maybe some wrong output (assuming, you are not supposed to print possible duplicates).

So I'd suggest to make a look-up first, of what you are looking (note, that maybe you want to take care about the novw[ay] situation there too).

Then iterate the list, you want to find the dupes in.

def m = [
    [id: 7144, name: "Test załącznika.docx", group: "3#Gotowe do akceptacji"],
    [id: 7145, name: "Test załącznika 2.docx", group: "3#Gotowe do akceptacji"],
    [id: 7146, name: "Test integracji dział prawny cd..docx", group: "3#Gotowe do akceptacji"],
    [id: 7147, name: "Test załącznika 3.docx", group: "3#Gotowe do akceptacji"],
    [id: 7153, name: "Z.8.DRWS.P.01.F.01.PL.01 Wykaz dokumentów związanych i załączników.docx", group: "3#Gotowe do akceptacji"],
    [id: 7154, name: "xoxoxoxx.docx", group: "3#Gotowe do akceptacji"], // to at least one missing
]

def mj = [
    [id: 24930, name: "Test integracji dział prawny cd. nowy.docx"],
    [id: 24931, name: "Test załącznika nowy.docx"],
    [id: 24932, name: "Test załącznika 3 nowa.docx"],
    [id: 23432, name: "xoxoxoxx.docx"],
    [id: 24933, name: "Test załącznika 2 nowy.docx"]
]


def stripSuffix = { it.take(it.lastIndexOf('.')) }

// XXX: maybe add now[ay] handling here
def known = mj.stream().map{ stripSuffix it.name }.toSet()

m.each{
    def webcNameWithoutExtension = stripSuffix(it.name)
    if (!known.contains(webcNameWithoutExtension)) {
        println webcNameWithoutExtension
    }
}
0
IWilms On

I would recommend two things:

  1. to turn the each-loops into for-loops to enable breaking out and
  2. switch iterating over m and mj.
def m = [
        [id: 7144, name: "Test załącznika.docx", group: "3#Gotowe do akceptacji"],
        [id: 7145, name: "Test załącznika 2.docx", group: "3#Gotowe do akceptacji"],
        [id: 7146, name: "Test integracji dział prawny cd..docx", group: "3#Gotowe do akceptacji"],
        [id: 7147, name: "Test załącznika 3.docx", group: "3#Gotowe do akceptacji"],
        [id: 7153, name: "Z.8.DRWS.P.01.F.01.PL.01 Wykaz dokumentów związanych i załączników.docx", group: "3#Gotowe do akceptacji"]
]

def mj = [
        [id: 24930, name: "Test integracji dział prawny cd. nowy.docx"],
        [id: 24931, name: "Test załącznika nowy.docx"],
        [id: 24932, name: "Test załącznika 3 nowa.docx"],
        [id: 23432, name: "xoxoxoxx.docx"],
        [id: 24933, name: "Test załącznika 2 nowy.docx"]
]

for (jiraFile in mj) {
    def jiraName = jiraFile.name
    def jiraNameWithoutExtension = jiraName.take(jiraName.lastIndexOf('.'))

    def found = false
    for (webcFile in m) {
        def webcName = webcFile.name
        def webcNameWithoutExtension = webcName.take(webcName.lastIndexOf('.'))
        def webcGroup = webcFile.group
        if (jiraNameWithoutExtension.contains(webcNameWithoutExtension) && webcGroup == "3#Gotowe do akceptacji") {
            found = true
            break
        }
    }
    if(!found)
        print(jiraNameWithoutExtension)
}

If you like a more functional approach you could try something like

List list = m.findAll { it.group == "3#Gotowe do akceptacji" }
        .collect { map -> getJiraNameWithoutExtension(map) }

mj.collect { map -> getJiraNameWithoutExtension(map) }
    .findAll { name ->  nameNotContainedInList(name, list) }
    .each { println it }


boolean nameNotContainedInList(String name, List<Map> list) {
    list.stream()
        .filter { s -> name.contains(s) }
        .findFirst()
        .isEmpty()
}

String getJiraNameWithoutExtension(Map jiraFile){
    String jiraName = jiraFile.name
    jiraName.take(jiraName.lastIndexOf('.'))
}