varias recorrer objetos eliminar elementos elemento dimensiones contar bidimensional array agregar javascript arrays merge

javascript - recorrer - js array 2 dimension



Cómo combinar dos matrices en JavaScript y desduplicar elementos (30)

ES6

array1.push(...array2) // => don''t remove duplication

O

[...array1,...array2] // => don''t remove duplication

O

[...new Set([...array1 ,...array2])]; // => remove duplication

Tengo dos matrices de JavaScript:

var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"];

Quiero que la salida sea:

var array3 = ["Vijendra","Singh","Shakya"];

La matriz de salida debe tener palabras repetidas eliminadas.

¿Cómo fusiono dos matrices en JavaScript para obtener solo los elementos únicos de cada matriz en el mismo orden en que se insertaron en las matrices originales?


DeDuplicate single o Merge y DeDuplicate múltiples entradas de matriz. Ejemplo a continuación.

Usando ES6 - Set, para de, desestructuración

Escribí esta función simple que toma múltiples argumentos de matriz. Hace más o menos lo mismo que la solución anterior, solo tiene un caso de uso más práctico. Esta función no concatena valores duplicados en una sola matriz, por lo que puede eliminarlos en una etapa posterior.

DEFINICIÓN DE CORTA FUNCIÓN (solo 9 líneas)

/** * This function merging only arrays unique values. It does not merges arrays in to array with duplicate values at any stage. * * @params ...args Function accept multiple array input (merges them to single array with no duplicates) * it also can be used to filter duplicates in single array */ function arrayDeDuplicate(...args){ let set = new Set(); // init Set object (available as of ES6) for(let arr of args){ // for of loops through values arr.map((value) => { // map adds each value to Set object set.add(value); // set.add method adds only unique values }); } return [...set]; // destructuring set object back to array object // alternativly we culd use: return Array.from(set); }

EJEMPLO DE USO CODEPEN :

// SCENARIO let a = [1,2,3,4,5,6]; let b = [4,5,6,7,8,9,10,10,10]; let c = [43,23,1,2,3]; let d = [''a'',''b'',''c'',''d'']; let e = [''b'',''c'',''d'',''e'']; // USEAGE let uniqueArrayAll = arrayDeDuplicate(a, b, c, d, e); let uniqueArraySingle = arrayDeDuplicate(b); // OUTPUT console.log(uniqueArrayAll); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 43, 23, "a", "b", "c", "d", "e"] console.log(uniqueArraySingle); // [4, 5, 6, 7, 8, 9, 10]


Un enfoque funcional con ES2015.

Siguiendo el enfoque funcional, una union de dos Array s es solo la composición de concat y filter . Para proporcionar un rendimiento óptimo, recurrimos al tipo de datos Set nativo, que está optimizado para búsquedas de propiedades.

De todos modos, la pregunta clave junto con una función de union es cómo tratar los duplicados. Las siguientes permutaciones son posibles:

Array A + Array B [unique] + [unique] [duplicated] + [unique] [unique] + [duplicated] [duplicated] + [duplicated]

Las dos primeras permutaciones son fáciles de manejar con una sola función. Sin embargo, los dos últimos son más complicados, ya que no puede procesarlos mientras confíe en las búsquedas de Set . Dado que el cambio a una simple búsqueda de propiedades del Object conllevaría un serio impacto en el rendimiento, la siguiente implementación simplemente ignora la tercera y cuarta permutación. Tendrías que construir una versión separada de union para apoyarlos.

// small, reusable auxiliary functions const comp = f => g => x => f(g(x)); const apply = f => a => f(a); const flip = f => b => a => f(a) (b); const concat = xs => y => xs.concat(y); const afrom = apply(Array.from); const createSet = xs => new Set(xs); const filter = f => xs => xs.filter(apply(f)); // de-duplication const dedupe = comp(afrom) (createSet); // the actual union function const union = xs => ys => { const zs = createSet(xs); return concat(xs) ( filter(x => zs.has(x) ? false : zs.add(x) ) (ys)); } // mock data const xs = [1,2,2,3,4,5]; const ys = [0,1,2,3,3,4,5,6,6]; // here we go console.log( "unique/unique", union(dedupe(xs)) (ys) ); console.log( "duplicated/unique", union(xs) (ys) );

De aquí en adelante, resulta trivial implementar una función unionn , que acepta cualquier número de arreglos (inspirados en los comentarios de naomik):

// small, reusable auxiliary functions const uncurry = f => (a, b) => f(a) (b); const foldl = f => acc => xs => xs.reduce(uncurry(f), acc); const apply = f => a => f(a); const flip = f => b => a => f(a) (b); const concat = xs => y => xs.concat(y); const createSet = xs => new Set(xs); const filter = f => xs => xs.filter(apply(f)); // union and unionn const union = xs => ys => { const zs = createSet(xs); return concat(xs) ( filter(x => zs.has(x) ? false : zs.add(x) ) (ys)); } const unionn = (head, ...tail) => foldl(union) (head) (tail); // mock data const xs = [1,2,2,3,4,5]; const ys = [0,1,2,3,3,4,5,6,6]; const zs = [0,1,2,3,4,5,6,7,8,9]; // here we go console.log( unionn(xs, ys, zs) );

Resulta que unionn es solo foldl (también conocido como Array.prototype.reduce ), que toma union como su reductor. Nota: Como la implementación no utiliza un acumulador adicional, generará un error cuando lo aplique sin argumentos.


¿Por qué no usas un objeto? Parece que estás tratando de modelar un conjunto. Esto no conservará el orden, sin embargo.

var set1 = {"Vijendra":true, "Singh":true} var set2 = {"Singh":true, "Shakya":true} // Merge second object into first function merge(set1, set2){ for (var key in set2){ if (set2.hasOwnProperty(key)) set1[key] = set2[key] } return set1 } merge(set1, set2) // Create set from array function setify(array){ var result = {} for (var item in array){ if (array.hasOwnProperty(item)) result[array[item]] = true } return result }


Aquí es una toma ligeramente diferente en el bucle. Con algunas de las optimizaciones en la última versión de Chrome, es el método más rápido para resolver la unión de las dos matrices (Chrome 38.0.2111).

jsperf.com/merge-two-arrays-keeping-only-unique-values

var array1 = ["Vijendra", "Singh"]; var array2 = ["Singh", "Shakya"]; var array3 = []; var arr = array1.concat(array2), len = arr.length; while (len--) { var itm = arr[len]; if (array3.indexOf(itm) === -1) { array3.unshift(itm); } }

bucle while: ~ 589k ops / s
filtro: ~ 445k ops / s
lodash: 308k ops / s
para bucles: 225k ops / s

Un comentario señaló que una de mis variables de configuración estaba causando que mi ciclo se adelantara al resto, porque no tenía que inicializar una matriz vacía para escribir. Estoy de acuerdo con eso, así que reescribí la prueba para igualar el campo de juego e incluí una opción aún más rápida.

http://jsperf.com/merge-two-arrays-keeping-only-unique-values/21

var whileLoopAlt = function(array1, array2) { var array3 = []; var arr = array1.concat(array2); var len = arr.length; var assoc = {}; while(len--) { var itm = arr[len]; if(!assoc[itm]) { // Eliminate the indexOf call array3.unshift(itm); assoc[itm] = true; } } return array3; };

En esta solución alternativa, he combinado una solución de matriz asociativa de una respuesta para eliminar la llamada .indexOf() en el bucle que estaba ralentizando mucho las cosas con un segundo bucle, e incluí algunas de las otras optimizaciones que otros usuarios han sugerido en Sus respuestas también.

La respuesta principal aquí con el bucle doble en cada valor (i-1) sigue siendo significativamente más lenta. A lodash todavía le está yendo bien, y todavía lo recomendaría a cualquiera que no le importe agregar una biblioteca a su proyecto. Para aquellos que no quieren, mi bucle while sigue siendo una buena respuesta y la respuesta del filtro tiene una gran presencia aquí, superando todas mis pruebas con la última versión de Canary Chrome (44.0.2360) hasta el momento de este escrito.

Echa un vistazo a la respuesta de Mike y la respuesta de Dan Stocker si quieres aumentar la velocidad. Esos son, con mucho, el más rápido de todos los resultados después de analizar casi todas las respuestas viables.


Combine un número ilimitado de matrices o no matrices y manténgalo único:

function flatMerge() { return Array.prototype.reduce.call(arguments, function (result, current) { if (!(current instanceof Array)) { if (result.indexOf(current) === -1) { result.push(current); } } else { current.forEach(function (value) { console.log(value); if (result.indexOf(value) === -1) { result.push(value); } }); } return result; }, []); } flatMerge([1,2,3], 4, 4, [3, 2, 1, 5], [7, 6, 8, 9], 5, [4], 2, [3, 2, 5]); // [1, 2, 3, 4, 5, 7, 6, 8, 9] flatMerge([1,2,3], [3, 2, 1, 5], [7, 6, 8, 9]); // [1, 2, 3, 5, 7, 6, 8, 9] flatMerge(1, 3, 5, 7); // [1, 3, 5, 7]



En Dojo 1.6+

var unique = []; var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"]; var array3 = array1.concat(array2); // Merged both arrays dojo.forEach(array3, function(item) { if (dojo.indexOf(unique, item) > -1) return; unique.push(item); });

Actualizar

Ver código de trabajo.

http://jsfiddle.net/UAxJa/1/


Esta es una solución de ECMAScript 6 que utiliza los operadores de propagación y los genéricos de matriz.

Actualmente solo funciona con Firefox y posiblemente con la Vista previa técnica de Internet Explorer.

Pero si usas Babel , puedes tenerlo ahora.

// Input: [ [1, 2, 3], [101, 2, 1, 10], [2, 1] ] // Output: [1, 2, 3, 101, 10] function mergeDedupe(arr) { return [...new Set([].concat(...arr))]; }


La mejor solucion...

Puedes consultar directamente en la consola del navegador pulsando ...

Sin duplicado

a = [1, 2, 3]; b = [3, 2, 1, "prince"]; a.concat(b.filter(function(el) { return a.indexOf(el) === -1; }));

Con duplicado

["prince", "asish", 5].concat(["ravi", 4])

Si lo desea, sin duplicado, puede intentar una mejor solución desde aquí: el Código de Shouting .

[1, 2, 3].concat([3, 2, 1, "prince"].filter(function(el) { return [1, 2, 3].indexOf(el) === -1; }));

Probar en la consola del navegador Chrome

f12 > console

Salida:

["prince", "asish", 5, "ravi", 4] [1, 2, 3, "prince"]


Mi centavo y medio

Array.prototype.concat_n_dedupe = function(other_array) { return this .concat(other_array) // add second .reduce(function(uniques, item) { // dedupe all if (uniques.indexOf(item) == -1) { uniques.push(item); } return uniques; }, []); }; var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"]; var result = array1.concat_n_dedupe(array2); console.log(result);


Nueva solución (que utiliza Array.prototype.indexOf y Array.prototype.concat ):

Array.prototype.uniqueMerge = function( a ) { for ( var nonDuplicates = [], i = 0, l = a.length; i<l; ++i ) { if ( this.indexOf( a[i] ) === -1 ) { nonDuplicates.push( a[i] ); } } return this.concat( nonDuplicates ) };

Uso:

>>> [''Vijendra'', ''Singh''].uniqueMerge([''Singh'', ''Shakya'']) ["Vijendra", "Singh", "Shakya"]

Array.prototype.indexOf (para Internet Explorer):

Array.prototype.indexOf = Array.prototype.indexOf || function(elt) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from): Math.floor(from); if (from < 0)from += len; for (; from < len; from++) { if (from in this && this[from] === elt)return from; } return -1; };


Para simplemente fusionar las matrices (sin eliminar duplicados)

Versión ES5 utiliza Array.concat :

var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"]; var array3 = array1.concat(array2); // Merges both arrays // [ ''Vijendra'', ''Singh'', ''Singh'', ''Shakya'' ]

La versión ES6 usa la destructuring

const array1 = ["Vijendra","Singh"]; const array2 = ["Singh", "Shakya"]; const array3 = [...array1, ...array2];

Como no hay una forma ''incorporada'' para eliminar duplicados ( ECMA-262 realidad tiene Array.forEach que sería ideal para esto), tenemos que hacerlo manualmente:

Array.prototype.unique = function() { var a = this.concat(); for(var i=0; i<a.length; ++i) { for(var j=i+1; j<a.length; ++j) { if(a[i] === a[j]) a.splice(j--, 1); } } return a; };

Entonces, para usarlo:

var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"]; // Merges both arrays and gets unique items var array3 = array1.concat(array2).unique();

Esto también preservará el orden de los arreglos (es decir, no es necesario clasificarlos).

Ya que muchas personas están molestas con el aumento de prototipo del Array.prototype y for in bucles, aquí hay una forma menos invasiva de usarlo:

function arrayUnique(array) { var a = array.concat(); for(var i=0; i<a.length; ++i) { for(var j=i+1; j<a.length; ++j) { if(a[i] === a[j]) a.splice(j--, 1); } } return a; } var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"]; // Merges both arrays and gets unique items var array3 = arrayUnique(array1.concat(array2));

Para aquellos que tienen la suerte de trabajar con navegadores donde está disponible ES5, puede usar Object.defineProperty siguiente manera:

Object.defineProperty(Array.prototype, ''unique'', { enumerable: false, configurable: false, writable: false, value: function() { var a = this.concat(); for(var i=0; i<a.length; ++i) { for(var j=i+1; j<a.length; ++j) { if(a[i] === a[j]) a.splice(j--, 1); } } return a; } });


Primero concatene las dos matrices, luego filtre solo los elementos únicos.

var a = [1, 2, 3], b = [101, 2, 1, 10]; var c = a.concat(b); var d = c.filter(function (item, pos) {return c.indexOf(item) == pos}); // d is [1,2,3,101,10]

http://jsfiddle.net/simo/98622/

Editar

Según lo sugerido por @Dmitry (ver el segundo comentario a continuación), una solución más inteligente en cuanto al rendimiento sería filtrar los elementos únicos en b antes de concatenar con a

var a = [1, 2, 3], b = [101, 2, 1, 10]; var c = a.concat(b.filter(function (item) { return a.indexOf(item) < 0; })); // d is [1,2,3,101,10]


Puedes hacerlo simplemente con ECMAScript 6,

var array1 = ["Vijendra", "Singh"]; var array2 = ["Singh", "Shakya"]; var array3 = [...new Set([...array1 ,...array2])]; console.log(array3); // ["Vijendra", "Singh", "Shakya"];

  • Utilice el operador de propagación para concatenar la matriz.
  • Use Set para crear un conjunto distinto de elementos.
  • Nuevamente use el operador de propagación para convertir el Conjunto en una matriz.

Puedes lograrlo simplemente usando Underscore.js''s => uniq :

array3 = _.uniq(array1.concat(array2)) console.log(array3)

Se imprimirá ["Vijendra", "Singh", "Shakya"] .


Se puede hacer usando Set.

var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"]; var array3 = array1.concat(array2); var tempSet = new Set(array3); array3 = Array.from(tempSet); //show output document.body.querySelector("div").innerHTML = JSON.stringify(array3);

<div style="width:100%;height:4rem;line-height:4rem;background-color:steelblue;color:#DDD;text-align:center;font-family:Calibri" > temp text </div>


Simplemente manténgase alejado de los bucles anidados (O (n ^ 2)), y .indexOf() (+ O (n)).

function merge(a, b) { var hash = {}, i; for (i=0; i<a.length; i++) { hash[a[i]]=true; } for (i=0; i<b.length; i++) { hash[b[i]]=true; } return Object.keys(hash); }


Simplificó la respuesta de simo y la convirtió en una buena función.

function mergeUnique(arr1, arr2){ return arr1.concat(arr2.filter(function (item) { return arr1.indexOf(item) === -1; })); }


Solo tirando mis dos centavos.

function mergeStringArrays(a, b){ var hash = {}; var ret = []; for(var i=0; i < a.length; i++){ var e = a[i]; if (!hash[e]){ hash[e] = true; ret.push(e); } } for(var i=0; i < b.length; i++){ var e = b[i]; if (!hash[e]){ hash[e] = true; ret.push(e); } } return ret; }

Este es un método que utilizo mucho, usa un objeto como una tabla hashlookup para realizar la comprobación de duplicados. Suponiendo que el hash es O (1), entonces esto se ejecuta en O (n) donde n es a.length + b.length. Sinceramente, no tengo idea de cómo el navegador hace el hash, pero funciona bien en muchos miles de puntos de datos.


Suponiendo que las matrices originales no necesiten desduplicación, esto debería ser bastante rápido, conservar el orden original y no modificar las matrices originales ...

function arrayMerge(base, addendum){ var out = [].concat(base); for(var i=0,len=addendum.length;i<len;i++){ if(base.indexOf(addendum[i])<0){ out.push(addendum[i]); } } return out; }

uso:

var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"]; var array3 = arrayMerge(array1, array2); console.log(array3); //-> [ ''Vijendra'', ''Singh'', ''Shakya'' ]


Usando un Set (ECMAScript 2015), será tan simple como eso:

const array1 = ["Vijendra", "Singh"]; const array2 = ["Singh", "Shakya"]; const array3 = Array.from(new Set(array1.concat(array2)));


fusionar dos matrices y eliminar duplicados en es6

let arr1 = [3, 5, 2, 2, 5, 5]; let arr2 = [2, 1, 66, 5]; let unique = [...new Set([...arr1,...arr2])]; console.log(unique); // [ 3, 5, 2, 1, 66 ]


Parece que la respuesta aceptada es la más lenta en mis pruebas;

nota que estoy fusionando 2 matrices de objetos por clave

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <button type=''button'' onclick=''doit()''>do it</button> <script> function doit(){ var items = []; var items2 = []; var itemskeys = {}; for(var i = 0; i < 10000; i++){ items.push({K:i, C:"123"}); itemskeys[i] = i; } for(var i = 9000; i < 11000; i++){ items2.push({K:i, C:"123"}); } console.time(''merge''); var res = items.slice(0); //method1(); method0(); //method2(); console.log(res.length); console.timeEnd(''merge''); function method0(){ for(var i = 0; i < items2.length; i++){ var isok = 1; var k = items2[i].K; if(itemskeys[k] == null){ itemskeys[i] = res.length; res.push(items2[i]); } } } function method1(){ for(var i = 0; i < items2.length; i++){ var isok = 1; var k = items2[i].K; for(var j = 0; j < items.length; j++){ if(items[j].K == k){ isok = 0; break; } } if(isok) res.push(items2[i]); } } function method2(){ res = res.concat(items2); for(var i = 0; i < res.length; ++i) { for(var j = i+1; j < res.length; ++j) { if(res[i].K === res[j].K) res.splice(j--, 1); } } } } </script> </body> </html>


Por el bien de esto ... aquí hay una solución de una sola línea:

const x = [...new Set([[''C'', ''B''],[''B'', ''A'']].reduce( (a, e) => a.concat(e), []))].sort() // [''A'', ''B'', ''C'']

No es particularmente legible pero puede ayudar a alguien:

  1. Aplica una función de reducción con el valor del acumulador inicial establecido en una matriz vacía.
  2. La función de reducción usa concat para agregar cada sub-matriz a la matriz del acumulador.
  3. El resultado de esto se pasa como un parámetro de constructor para crear un nuevo Set.
  4. El operador de propagación se utiliza para convertir el Seta una matriz.
  5. La sort()función se aplica a la nueva matriz.

La forma más fácil de hacer esto es usarlo concat()para combinar los arreglos y luego usarlos filter()para eliminar los duplicados, o usarlos concat()y luego colocarlos dentro de una Set().

Primera forma:

const firstArray = [1,2, 2]; const secondArray = [3,4]; // now lets merge them const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4] //now use filter to remove dups const removeDuplicates = mergedArray.filter((elem, index) => mergedArray.indexOf(elem) === index); // [1,2,3, 4]

Segunda forma (pero con implicaciones de rendimiento en la interfaz de usuario):

const firstArray = [1,2, 2]; const secondArray = [3,4]; // now lets merge them const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4] const removeDuplicates = new Set(mergedArray);


//Array.indexOf was introduced in javascript 1.6 (ECMA-262) //We need to implement it explicitly for other browsers, if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(elt, from) { var len = this.length >>> 0; for (; from < len; from++) { if (from in this && this[from] === elt) return from; } return -1; }; } //now, on to the problem var array1 = ["Vijendra","Singh"]; var array2 = ["Singh", "Shakya"]; var merged = array1.concat(array2); var t; for(i = 0; i < merged.length; i++) if((t = merged.indexOf(i + 1, merged[i])) != -1) { merged.splice(t, 1); i--;//in case of multiple occurrences }

La implementación del método indexOf para otros navegadores está tomada de MDC


Array.prototype.add = function(b){ var a = this.concat(); // clone current object if(!b.push || !b.length) return a; // if b is not an array, or empty, then return a unchanged if(!a.length) return b.concat(); // if original is empty, return b // go through all the elements of b for(var i = 0; i < b.length; i++){ // if b''s value is not in a, then add it if(a.indexOf(b[i]) == -1) a.push(b[i]); } return a; } // Example: console.log([1,2,3].add([3, 4, 5])); // will output [1, 2, 3, 4, 5]


Array.prototype.merge = function(/* variable number of arrays */){ for(var i = 0; i < arguments.length; i++){ var array = arguments[i]; for(var j = 0; j < array.length; j++){ if(this.indexOf(array[j]) === -1) { this.push(array[j]); } } } return this; };

Una mucho mejor función de combinación de matriz.


array1.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)

Lo bueno de este es el rendimiento y que, en general, cuando trabaja con matrices, está encadenando métodos como el filtro, el mapa, etc., por lo que puede agregar esa línea y concateará y deduplicará array2 con array1 sin necesidad de una referencia a la siguiente. uno (cuando está encadenando métodos que no tiene), ejemplo:

someSource() .reduce(...) .filter(...) .map(...) // and now you want to concat array2 and deduplicate: .concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos) // and keep chaining stuff .map(...) .find(...) // etc

(No me gusta contaminar Array.prototipo y esa sería la única forma de respetar la cadena: definir una nueva función la romperá, así que creo que algo como esto es la única forma de lograrlo)