Tengo un objeto que contiene una matriz de objetos.
things = new Object();
things.thing = new Array();
things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});
Me pregunto cuál es el mejor método para eliminar objetos duplicados de una matriz. Entonces, por ejemplo, las cosas se volverían ...
{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}
javascript
arrays
object
duplicates
Travis
fuente
fuente
aaaaa.aaaa.push(...)
:)Respuestas:
Un método primitivo sería:
fuente
¿Qué tal con algo de
es6
magia?URL de referencia
Una solución más genérica sería:
Ejemplo de Stackblitz
fuente
things.thing = things.thing.filter((thing, index, self) => self.findIndex(t => t.place === thing.place && t.name === thing.name) === index)
const uniqueArray = arrayOfObjects.filter((object,index) => index === arrayOfObjects.findIndex(obj => JSON.stringify(obj) === JSON.stringify(object)));
jsfiddle.net/x9ku0p7L/28Si puede usar bibliotecas de Javascript, como subrayado o lodash, le recomiendo echar un vistazo a la
_.uniq
función en sus bibliotecas. Delodash
:Básicamente, pasa la matriz que aquí es un objeto literal y pasa el atributo con el que desea eliminar los duplicados en la matriz de datos original, de esta manera:
ACTUALIZACIÓN : Lodash ahora ha introducido un
.uniqBy
también.fuente
uniqBy
lugar deuniq
, por ejemplo,_.uniqBy(data, 'name')
documentación: lodash.com/docs#uniqByTenía exactamente el mismo requisito, para eliminar objetos duplicados en una matriz, basados en duplicados en un solo campo. Encontré el código aquí: Javascript: eliminar duplicados de la matriz de objetos
Entonces, en mi ejemplo, estoy eliminando cualquier objeto de la matriz que tenga un valor de cadena duplicado licenseNum.
Los resultados:
uniqueArray es:
fuente
for(var i in array) { if(array[i][prop]){ //valid lookupObject[array[i][prop]] = array[i]; } else { console.log('falsy object'); } }
for (let i in originalArray) { if (lookupObject[originalArray[i]['id']] === undefined) { newArray.push(originalArray[i]); } lookupObject[originalArray[i]['id']] = originalArray[i]; }
Los revestimientos más cortos para ES6 +
Encuentra los únicos
id
en una matriz.Único por múltiples propiedades (
place
yname
)Único por todas las propiedades (Esto será lento para matrices grandes)
Mantener la última ocurrencia.
fuente
Un revestimiento usando Set
Explicación:
new Set(myData.map(JSON.stringify))
crea un objeto Set utilizando los elementos myData en cadena.fuente
Usando ES6 + en una sola línea, puede obtener una lista única de objetos por clave:
Se puede poner en una función:
Aquí hay un ejemplo de trabajo:
Como funciona
Primero, la matriz se reasigna de manera que se pueda usar como entrada para un Mapa.
lo que significa que cada elemento de la matriz se transformará en otra matriz con 2 elementos; la clave seleccionada como primer elemento y todo el elemento inicial como segundo elemento, esto se llama una entrada (por ejemplo , entradas de matriz , entradas de mapa ). Y aquí está el documento oficial con un ejemplo que muestra cómo agregar entradas de matriz en Map constructor.
Ejemplo cuando la clave es lugar :
En segundo lugar, pasamos esta matriz modificada al constructor del Mapa y aquí está sucediendo la magia. Map eliminará los valores duplicados de las claves, manteniendo solo el último valor insertado de la misma clave. Nota : El mapa mantiene el orden de inserción. ( marque la diferencia entre Mapa y objeto )
En tercer lugar, usamos los valores del mapa para recuperar los elementos originales, pero esta vez sin duplicados.
Y el último es agregar esos valores en una nueva matriz nueva para que pueda verse como la estructura inicial y devolver eso:
fuente
id
. La pregunta necesita todo el objeto a ser únicos en todos los campos, tales comoplace
ename
Aquí hay otra opción para hacerlo utilizando los métodos de iteración de Array si necesita comparar solo un campo de un objeto:
fuente
un trazador de líneas está aquí
fuente
Si puede esperar para eliminar los duplicados hasta después de todas las adiciones, el enfoque típico es primero ordenar la matriz y luego eliminar los duplicados. La clasificación evita el enfoque N * N de escanear la matriz para cada elemento a medida que los recorre.
La función "eliminar duplicados" generalmente se llama única o uniq . Algunas implementaciones existentes pueden combinar los dos pasos, por ejemplo, uniq de prototipo
¡Esta publicación tiene algunas ideas para probar (y algunas para evitar :-)) si su biblioteca aún no tiene una ! Personalmente, creo que este es el más sencillo:
fuente
function(_a,_b){return _a.a===_b.a && _a.b===_b.b;}
entonces la matriz no se ordenará.La forma más simple es usar
filter
:fuente
id
. La pregunta necesita que todo el objeto sea único en todos los campos, tales comoplace
yname
Esta es una forma genérica de hacer esto: pasa una función que prueba si dos elementos de una matriz se consideran iguales. En este caso, compara los valores de las propiedades
name
yplace
de los dos objetos que se comparan.Respuesta ES5
Respuesta original de ES3
fuente
Para agregar uno más a la lista. Usando ES6 y
Array.reduce
conArray.find
.En este ejemplo, filtrar objetos basados en una
guid
propiedad.Extendiendo este para permitir la selección de una propiedad y comprimirla en un solo revestimiento:
Para usarlo, pase una matriz de objetos y el nombre de la clave que desea deducir como valor de cadena:
fuente
También puedes usar un
Map
:Muestra completa:
Resultado:
fuente
Dang, niños, aplastemos esto, ¿por qué no lo hacemos?
fuente
id
. La pregunta necesita que todo el objeto sea único en todos los campos comoplace
yname
place
yname
hoy. Cualquiera que lea este hilo está buscando una manera óptima de deducir una lista de objetos, y esta es una forma compacta de hacerlo.Una solución TypeScript
Esto eliminará los objetos duplicados y también preservará los tipos de los objetos.
fuente
Considerando
lodash.uniqWith
fuente
Otra opción sería crear una función indexOf personalizada, que compare los valores de su propiedad elegida para cada objeto y la ajuste en una función de reducción.
fuente
lodash.isequal
combiné con el paquete npm como un comparador de objetos livianos para realizar un filtrado de matriz único ... por ejemplo, una matriz distinta de objetos. Acabo de cambiar enif (_.isEqual(a[i], b)) {
lugar de buscar @ una sola propiedadOne-liner usando ES6 y
new Map()
.Detalles: -
.map()
en la lista de datos y convertir cada objeto individual en una[key, value]
matriz de pares (longitud = 2), el primer elemento (clave) sería lastringified
versión del objeto y el segundo (valor) sería unobject
sí mismo.new Map()
tendría la clave comostringified
objeto y cualquier misma adición de clave resultaría en la anulación de la clave ya existente..values()
daría MapIterator con todos los valores en un Mapa (obj
en nuestro caso)spread ...
operador para dar una nueva matriz con los valores del paso anterior.fuente
Aquí hay una solución para es6 donde solo desea conservar el último elemento. Esta solución es funcional y cumple con el estilo Airbnb.
fuente
removeDuplicates () toma una matriz de objetos y devuelve una nueva matriz sin ningún objeto duplicado (basado en la propiedad id).
Gastos esperados:
Primero, establecemos el valor de la variable uniq en un objeto vacío.
A continuación, filtramos a través de la matriz de objetos. Filter crea una nueva matriz con todos los elementos que pasan la prueba implementada por la función proporcionada.
Arriba, utilizamos la funcionalidad de cortocircuito de &&. Si el lado izquierdo de && se evalúa como verdadero, entonces devuelve el valor a la derecha de &&. Si el lado izquierdo es falso, devuelve lo que está en el lado izquierdo de &&.
Para cada objeto (obj) verificamos uniq para una propiedad llamada valor de obj.id (en este caso, en la primera iteración verificaría la propiedad '1'). Queremos lo contrario de lo que devuelve (ya sea verdadero o falso) por eso usamos el! in! uniq [obj.id]. Si uniq ya tiene la propiedad id, devuelve verdadero que se evalúa como falso (!) Indicando a la función de filtro que NO agregue ese obj. Sin embargo, si no encuentra la propiedad obj.id, devuelve falso, que luego se evalúa como verdadero (!) Y devuelve todo a la derecha de &&, o (uniq [obj.id] = verdadero). Este es un valor verdadero, que le dice al método de filtro que agregue ese obj a la matriz devuelta, y también agrega la propiedad {1: true} a uniq. Esto asegura que cualquier otra instancia de obj con esa misma identificación no se agregará nuevamente.
fuente
fuente
Creo que una combinación de
reduce
conJSON.stringify
a la perfección comparar objetos y selectivamente la adición de los que no están ya en el acumulador es una manera elegante.Tenga en cuenta que
JSON.stringify
podría convertirse en un problema de rendimiento en casos extremos donde la matriz tiene muchos Objetos y son complejos, PERO para la mayoría de las veces , esta es la forma más corta de ir en mi humilde opinión.Otra forma de escribir lo mismo (pero menos eficiente):
fuente
Continuar explorando formas de ES6 de eliminar duplicados de una matriz de objetos: establecer el
thisArg
argumento deArray.prototype.filter
tonew Set
proporciona una alternativa decente:Sin embargo, no funcionará con funciones de flecha
() =>
, ya quethis
está vinculado a su alcance léxico.fuente
es6 magia en una línea ... ¡legible en eso!
fuente
Solución simple con los métodos auxiliares de matriz 'reduce' y 'find' de ES6
Funciona de manera eficiente y perfectamente bien!
fuente
Si no le importa que su matriz única se ordene después, esta sería una solución eficiente:
De esta manera, solo tiene que comparar el elemento actual con el elemento anterior en la matriz. Ordenar una vez antes de filtrar (
O(n*log(n))
) es más barato que buscar un duplicado en toda la matriz para cada elemento de la matriz (O(n²)
).fuente
Esta es una manera simple de cómo eliminar la duplicidad de la matriz de objetos.
Trabajo mucho con datos y esto es útil para mí.
se imprimirá en la consola:
fuente
str es una matriz de objetos. Existen objetos que tienen el mismo valor (aquí un pequeño ejemplo, hay dos objetos que tienen el mismo item_id que 2). check (id) es una función que verifica si existe o no algún objeto que tenga el mismo item_id. si existe, devuelve falso; de lo contrario, devuelve verdadero. De acuerdo con ese resultado, inserte el objeto en una nueva matriz obj La salida del código anterior es
[{"item_id":1},{"item_id":2}]
fuente
¿Has oído hablar de la biblioteca Lodash? Le recomiendo esta utilidad, cuando realmente no desea aplicar su lógica al código, y usar el código ya presente que es optimizado y confiable.
Considere hacer una matriz como esta
Tenga en cuenta que si desea mantener un atributo único, puede hacerlo utilizando la biblioteca lodash. Aquí, puedes usar _.uniqBy
Este método es como _.uniq (que devuelve una versión libre de duplicados de una matriz, en la que solo se mantiene la primera aparición de cada elemento), excepto que acepta iteratee que se invoca para cada elemento de la matriz para generar el criterio por el cual Se calcula la unicidad.
Entonces, por ejemplo, si desea devolver una matriz que tenga un atributo único de 'lugar'
Del mismo modo, si desea un atributo único como 'nombre'
Espero que esto ayude.
¡Salud!
fuente