Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

250
Vistas
¿Por qué mi función de recursión JS devuelve una lista con la misma entrada?

He estado aprendiendo Python en la escuela y estoy aprendiendo JavaScript en mi propio tiempo y abordando algunos proyectos de JS. No puedo entender por qué mi función de recurrencia es solo una lista con la misma entrada.

Descripción de la función: la función toma una lista de objetos del curso, con pares clave-valor "courseCode": string y "combos "possibleCombos": list[number] . Quiero que mi función recursiva genere otra lista de Objetos, con el valor "código del curso" del Objeto del curso como sus claves, y un elemento de los "combos posibles" como su valor. La lista devuelta tendrá todas las permutaciones posibles de los Objetos con pares curso-combo. La función también toma un parámetro de objeto, con fines de recursividad.

Datos de ejemplo:

 const dummyObject1 = { 'courseCode': 'BLUE', 'possibleCombos': [1, 2, 3, 4, 5] } const dummyObject2 = { 'courseCode': 'RED', 'possibleCombos': [11, 22, 33, 44] } const dummyObject3 = { 'courseCode': 'PURPLE', 'possibleCombos': [111, 222, 333, 444, 555, 666] } const dummyList = [dummyObject1, dummyObject2, dummyObject3]```

Idealmente quiero:

 let dummySchedules = recursionFunction(dummyList, {}) console.log(dummySchedules) //ideal console output [ {'BLUE': 1, 'RED': 11, 'PURPLE': 111}, {'BLUE': 1, 'RED': 11, 'PURPLE': 222}, {'BLUE': 1, 'RED': 11, 'PURPLE': 333}, ... //and so on. ]

Sin embargo, el resultado de la lista que obtengo es solo 120 entradas del mismo objeto.

Aquí está mi código:

 function recursiveFunction(listOfCourses, dictSoFar) { //base case, checks if listOfCourses is empty if (!listOfCourses.length) { return [dictSoFar] } else { //recursive step var arraySoFar = [] //accumulator //iterate through each element of listOfCourses[0]['possibleCombos'] for (let combo of listOfCourses[0]['possibleCombos']) { //update dictSoFar entry. dictSoFar[listOfCourses[0]['courseCode']] = combo //filter out the course we just entered into dictSoFar. let course = listOfCourses[0] var cloneListOfCourses = listOfCourses.filter(item => item !== course) //recursive call, this time with the filtered out list. If we keep following the //the recursive call down, it should reach the point where listOfCourses is empty, //triggering the base case. At that point, dictSoFar already has all course: combo //pairs. This should traverse through all possible course: combo pairs. var result = recursiveFunction(cloneListOfCourses, dictSoFar) //update the accumulator arraySoFar.push(...result) } return arraySoFar; } }

¿Lo que está sucediendo? En teoría, creo que la lógica tiene sentido, y no puedo decir dónde está fallando.

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

puedes hacer algo como esto

si necesitas alguna explicación no dudes en preguntar

 const dummyObject1 = { 'courseCode': 'BLUE', 'possibleCombos': [1, 2, 3, 4, 5] } const dummyObject2 = { 'courseCode': 'RED', 'possibleCombos': [11, 22, 33, 44] } const dummyObject3 = { 'courseCode': 'PURPLE', 'possibleCombos': [111, 222, 333, 444, 555, 666] } const dummyList = [dummyObject1, dummyObject2, dummyObject3] function recursiveFunction(listOfCourses) { const loop = (data, acc) => { if (!data.length) { // if listOfCourses is falsy return acc } const [next, ...rest] = data if(acc.length === 0){ return loop(rest, next) } return loop(rest, next.flatMap(n => acc.flatMap(a => Object.assign({}, a, n)))) } const courseCombo = listOfCourses.map(({ courseCode, possibleCombos }) => possibleCombos.map(c => ({ [courseCode]: c }))) return loop(courseCombo, []) } console.log(recursiveFunction(dummyList))

Salí con una solución más simple que no implica recursividad en absoluto.

se divide en dos pasos:

la primera transformación mapea tu objeto ficticio en una matriz de elementos con esta forma

 [{ BLUE : 1}, { BLUE : 2},{ BLUE : 3}, { BLUE : 4}, { BLUE : 5}]

luego, al usar reduce , se fusionan todas las combinaciones de las tres matrices juntas

 const dummyObject1 = { 'courseCode': 'BLUE', 'possibleCombos': [1, 2, 3, 4, 5] } const dummyObject2 = { 'courseCode': 'RED', 'possibleCombos': [11, 22, 33, 44] } const dummyObject3 = { 'courseCode': 'PURPLE', 'possibleCombos': [111, 222, 333, 444, 555, 666] } const dummyList = [dummyObject1, dummyObject2, dummyObject3] const result = dummyList .map(({courseCode, possibleCombos}) => possibleCombos.map(c => ({[courseCode]: c}))) .reduce((res, item) => res.flatMap(r => item.flatMap(i => Object.assign({}, r, i)))) console.log(result)

about 4 years ago · Juan Pablo Isaza Denunciar

0

Lo que está buscando generalmente se llama el producto cartesiano de las listas. Con un poco de manipulación, podemos convertir sus entradas en matrices como [{BLUE: 1}, {BLUE: 2}, /*...,*/ {BLUE: 5}] , luego hacer un producto cartesiano de su colección de estos para obtener algo como [[{BLUE: 1}, {RED: 11}, {PURPLE: 111}], [{BLUE: 1}, {RED: 11}, {PURPLE: 222}, /...,*/ [{BLUE: 5}, {RED: 44}, {PURPLE: 666}]] . Luego, podemos simplemente llamar a Object.assign en cada una de estas matrices para obtener el resultado final.

El código termina siendo bastante simple.

 const cartesian = ([xs, ...xss]) => xs == undefined ? [[]] : xs .flatMap (x => cartesian (xss) .map (ys => [x, ...ys])) const spreadCombos = ({courseCode, possibleCombos}) => possibleCombos .map (v => ({[courseCode]: v})) const combine = (os) => cartesian (os .map (spreadCombos)) .map (xs => Object .assign ({}, ... xs)) const dummyObject1 = {courseCode: 'BLUE', possibleCombos: [1, 2, 3, 4, 5]}, dummyObject2 = {courseCode: 'RED', possibleCombos: [11, 22, 33, 44]}, dummyObject3 = {courseCode: 'PURPLE', possibleCombos: [111, 222, 333, 444, 555, 666]} const dummyList = [dummyObject1, dummyObject2, dummyObject3] console .log (combine (dummyList))
 .as-console-wrapper {max-height: 100% !important; top: 0}

cartesian hace el producto cartesiano de una matriz de matrices.

spreadCombos hace esa primera transformación de su entrada en [{BLUE: 1}, {BLUE: 2}, /*...,*/ {BLUE: 5}]

Y nuestra función principal combine primero llama a spreadCombos en cada elemento de entrada, llama a cartesian y luego, para cada matriz resultante, llama a Object.assign .

Tenga en cuenta que tenemos que iniciar nuestras llamadas Object .assign con un objeto vacío. En el formato intermedio, las instancias de, digamos, {BLUE: 1} son todas referencias al mismo objeto. Si simplemente distribuimos nuestra matriz como los únicos parámetros para Object .assign , entonces estaríamos modificando la misma referencia cada vez.

Esto también ayuda a explicar lo que está mal con su función. Pasa a través de dictSoFar como una referencia a un objeto y, por lo tanto, actualiza continuamente ese mismo objeto. Puede solucionar esto pasando un clon del objeto en su llamada recursiva. Para este propósito, podemos arreglárnoslas con el clon superficial {...dictSoFar} , aunque otras circunstancias pueden requerir un clon más profundo. Así que este parche debería corregir su enfoque:

 - var result = recursiveFunction(cloneListOfCourses, dictSoFar) + var result = recursiveFunction(cloneListOfCourses, {...dictSoFar})
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda