El último valor de la lista es reemplazar todos los otros valores mientras se establece dentro de los bucles en Groovy

Pregunta:

def responseTemp = [] 
def response = [:]
   loop1.each { row1 -> 
   loop2.each (row2 -> 
   loop3.each {row3 -> 
   loop4.each {row4 -> 
      response << ['field1' : 'row1.value1'] 
      response << ['field2' : 'row2.value1'] 
      response << ['field3' : 'row3.value1'] 
      responseTemp.add(response) 
      } 
     } 
    }  
   } 
println (responseTemp)

Resultado esperado es que debería tener toda la respuesta (la mina corre 10 veces) así que debería ver todas las 10 respuestas en respuestaTemp. Pero lo que veo si sólo la 10a respuesta 10 veces en respuestaTemp.

¿Cómo puedo añadir toda respuesta en respuestaTemp mientras iteramos y devolvemos eso al final.

Pregunta hecha hace 3 años, 4 meses, 29 días - Por csscraftsman


3 Respuestas:

  • Desde que te aferras a tu mapa para añadir a los resultados sobre todos los elementos su producto cartesiano, siempre añadir el mismo mapa al resultado. Y ya que anulas siempre las mismas llaves, el mapa contendrá el artículos de la última iteración.

    Solución sencilla: mover el def response en lo más íntimo cada una de ellas.

    Sin embargo, también puede no utilizar una variable en absoluto y un mapa literal en su lugar. Por ejemplo.

    def responseTemp = [] 
    [1,2].each{ row1 -> 
        [3,4].each{ row2 -> 
            responseTemp.add([field1: row1, field2: row2])
        }  
    } 
    println (responseTemp)
    // → [[field1:1, field2:3], [field1:1, field2:4], [field1:2, field2:3], [field1:2, field2:4]]
    

    Si prefiere una manera más declarativa, también puede utilizar collectMany on los bucles exteriores y finalmente collect en lo más íntimo. Por ejemplo.

    def responseTemp = [1,2].collectMany{ row1 -> 
        [3,4].collectMany{ row2 -> 
            [5,6].collect{ row3 -> 
                [field1: row1, field2: row2, field3: row3]
            }  
        }  
    } 
    println (responseTemp)
    // → [[field1:1, field2:3, field3:5], [field1:1, field2:3, field3:6], [field1:1, field2:4, field3:5], [field1:1, field2:4, field3:6], [field1:2, field2:3, field3:5], [field1:2, field2:3, field3:6], [field1:2, field2:4, field3:5], [field1:2, field2:4, field3:6]]
    

    Respondida el Dec 16, 2020 a las 16:28 - por coderchampion

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando se debe a que estás modificando el mismo objeto response en cada iteración, y al agregarlo a responseTemp, estás agregando una referencia al mismo objeto, por lo que al final responseTemp contendrá 10 referencias al mismo objeto response (que contendrá la última respuesta).

    Para solucionar este problema, debes crear un nuevo objeto response en cada iteración. Puedes hacerlo de la siguiente manera:

    groovy
    def responseTemp = []
    loop1.each { row1 -> 
        loop2.each { row2 -> 
            loop3.each { row3 -> 
                loop4.each { row4 -> 
                    def response = [:] // Crear un nuevo objeto response en cada iteración
                    response << ['field1': row1.value1] 
                    response << ['field2': row2.value1] 
                    response << ['field3': row3.value1] 
                    responseTemp.add(response) 
                } 
            } 
        }  
    } 
    println(responseTemp)
    

    De esta manera, en cada iteración se crea un nuevo objeto response que se llena con los valores correspondientes y se agrega a responseTemp, garantizando que cada elemento de responseTemp sea una respuesta independiente.

    Respondida el Dec 17, 2020 a las 16:23 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema en tu código es que estás reasignando response dentro de cada iteración de los bucles, lo que provoca que solo el último valor se guarde en responseTemp. Para resolver este problema, debes crear una nueva instancia de response dentro de cada iteración del bucle más externo y agregarla a responseTemp.

    Aquí tienes el código corregido:

    groovy
    def responseTemp = []
    loop1.each { row1 ->
      loop2.each { row2 ->
        loop3.each { row3 ->
          loop4.each { row4 ->
            def response = [:]
            response << ['field1': 'row1.value1']
            response << ['field2': 'row2.value1']
            response << ['field3': 'row3.value1']
            responseTemp.add(response)
          }
        }
      }
    }
    println(responseTemp)
    

    Ahora, cada iteración del bucle más externo creará una nueva instancia de response y la agregará a responseTemp, lo que dará como resultado la lista esperada de todas las respuestas.

    Respondida el Dec 17, 2020 a las 16:38 - por Gemini

    Votos positivos: 0 | Votos negativos: 0