recorrer objetos objeto lista diccionario convertir buscar array agregar javascript arrays merge lodash

javascript - lista - Combinar matriz de objetos por propiedad usando Lodash



recorrer array de objetos javascript (6)

Tengo dos matrices de objetos que representan direcciones de correo electrónico que tienen una etiqueta y un valor:

var original = [ { label: ''private'', value: ''[email protected]'' }, { label: ''work'', value: ''[email protected]'' } ]; var update = [ { label: ''private'', value: ''[email protected]'' }, { label: ''school'', value: ''[email protected]'' } ];

Ahora quiero comparar y combinar las dos matrices por el campo de label , para que el resultado se vea así:

var result = [ { label: ''private'', value: ''[email protected]'' }, { label: ''work'', value: ''[email protected]'' }, { label: ''school'', value: ''[email protected]'' } ]

¿Cómo puedo hacer esto, por ejemplo, utilizando lodash ?


Aquí he creado otro jsfiddle [https://jsfiddle.net/a0b8f6wg/][1] para fusionar dos matrices de objetos usando Lodash.


Convierta las listas en objetos codificados por label , _.assign por _.assign y _.assign nuevo a una matriz. Incluso mantendrá el orden de los elementos en la mayoría de los navegadores.

var original = [ { label: ''private'', value: ''[email protected]'' }, { label: ''work'', value: ''[email protected]'' } ]; var update = [ { label: ''private'', value: ''[email protected]'' }, { label: ''school'', value: ''[email protected]'' } ]; console.log( _.map( _.assign( _.mapKeys(original, v => v.label), _.mapKeys(update, v => v.label) ) ) ); // or remove more duplicated code using spread console.log( _.map( _.assign( ...[original, update].map( coll => _.mapKeys(coll, v => v.label) ) ) ) );

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.js"></script>


En caso de que esté utilizando lodash 3.x donde _.unionBy () no estaba allí, puede combinar _.union() y _.uniq() para obtener el mismo resultado.

var original = [ { label: ''private'', value: ''[email protected]'' }, { label: ''work'', value: ''[email protected]'' } ]; var update = [ { label: ''private'', value: ''[email protected]'' }, { label: ''school'', value: ''[email protected]'' } ]; var result = _.uniq(_.union(update, original), "label"); console.log(result);


Quizás un poco tarde, pero todas las soluciones que he visto no se unen a las dos matrices correctamente, usan una de las matrices para hacer un bucle y los elementos en exceso de la segunda matriz no se agregan (asumiendo que esto es lo que se requiere) .

La forma correcta es ordenar ambas matrices y avanzar dentro de ambas matrices, fusionando los elementos de coincidencias y agregando los elementos faltantes de ambas matrices. Por favor encuentre la solución completa a continuación. Esto también toma O (n + m) que es lo mejor que puede obtener (sin los costos computacionales para la clasificación en sí). En mi código ya tengo los datos ordenados de la base de datos.

function mergeObjectsBasedOnKey(array1, array2, compareFn, mergeFn, alreadySorted) { var array1Index = 0; var array2Index = 0; const merged = []; if (!alreadySorted) { array1.sort(compareFn); array2.sort(compareFn); } while (array1Index < array1.length && array2Index < array2.length) { var comparedValue = compareFn(array1[array1Index], array2[array2Index]); if (comparedValue === 0) { merged.push(mergeFn(array1[array1Index], array2[array2Index])); array1Index++; array2Index++; } else if (comparedValue < 0) { merged.push(mergeFn(array1[array1Index])); array1Index++; } else { merged.push(mergeFn(array2[array2Index])); array2Index++; } } while (array1Index < array1.length) { merged.push(mergeFn(array1[array1Index])); array1Index++; } while (array2Index < array2.length) { merged.push(mergeFn(array2[array2Index])); array2Index++; } return merged; } const array1 = [{ "id": 10, isArray1: true }, { "id": 11, isArray1: true }, { "id": 12, isArray1: true }, ]; const array2 = [{ "id": 8, isArray2: true }, { "id": 11, isArray2: true }, { "id": 15, isArray2: true }, ]; const result = mergeObjectsBasedOnKey(array1, array2, function(a, b) { return a.id - b.id; }, function(a, b) { if (b) { return _.merge(a, b); } return _.merge(a, { isArray1: true, isArray2: true }); }); console.log(result);

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Y los resultados serían:

[ { id: 8, isArray2: true, isArray1: true }, { id: 10, isArray1: true, isArray2: true }, { id: 11, isArray1: true, isArray2: true }, { id: 12, isArray1: true, isArray2: true }, { id: 15, isArray2: true, isArray1: true } ]


Sé que no es lo que se pide, pero en caso de que alguien se haya topado en esta página aquí es cómo haces esto en Ramda:

var original = [ { label: ''private'', value: ''[email protected]'' }, { label: ''work'', value: ''[email protected]'' } ]; var updated = [ { label: ''private'', value: ''[email protected]'' }, { label: ''school'', value: ''[email protected]'' } ]; unionWith(eqBy(prop(''label'')), updated, original);


_.unionBy() :
Este método es como _.union, excepto que acepta iterador que se invoca para cada elemento de cada matriz para generar el criterio por el cual se calcula la singularidad. Los valores de los resultados se eligen de la primera matriz en la que se produce el valor .

var original = [ { label: ''private'', value: ''[email protected]'' }, { label: ''work'', value: ''[email protected]'' } ]; var update = [ { label: ''private'', value: ''[email protected]'' }, { label: ''school'', value: ''[email protected]'' } ]; var result = _.unionBy(update, original, "label"); console.log(result);

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>