remove react objects from empty array javascript underscore.js unique lodash

javascript - react - subrayado/lodash único por múltiples propiedades



lodash react (4)

Tengo una matriz de objetos con duplicados y estoy tratando de obtener un listado único, donde la singularidad se define por un subconjunto de las propiedades del objeto. Por ejemplo,

{a:"1",b:"1",c:"2"}

Y quiero ignorar c en la comparación de la singularidad.

Puedo hacer algo como

_.uniq(myArray,function(element) { return element.a + "_" + element+b});

Esperaba poder hacer

_.uniq(myArray,function(element) { return {a:element.a, b:element.b} });

Pero eso no funciona. ¿Hay algo como lo que puedo hacer o debo crear una representación comparable del objeto si estoy comparando varias propiedades?


Creo que el enfoque de join () sigue siendo el más simple. A pesar de las preocupaciones planteadas en la solución anterior, creo que elegir el separador correcto es la clave para evitar las dificultades identificadas (con diferentes conjuntos de valores que devuelven el mismo valor unido). Tenga en cuenta que el separador no necesita ser un solo carácter, puede ser cualquier cadena en la que esté seguro de que no ocurrirá naturalmente en los datos en sí. Hago esto todo el tiempo y me gusta usar ''~! $ ~'' Como mi separador. También puede incluir caracteres especiales como / t / r / n etc.

Si los datos contenidos son realmente tan impredecibles, tal vez se conozca la longitud máxima y usted podría simplemente rellenar cada elemento hasta su longitud máxima antes de unirse.


Desafortunadamente, no parece haber una forma directa de hacer esto. Aparte de escribir su propia función para esto, tendrá que devolver algo que pueda compararse directamente por igualdad (como en su primer ejemplo).

Un método sería simplemente .join() las propiedades que necesita:

_.uniqBy(myArray, function(elem) { return [elem.a, elem.b].join(); });

Alternativamente, puedes usar _.pick o _.omit para eliminar lo que no necesites. A partir de ahí, puede usar _.values con un .join() , o incluso solo JSON.stringify :

_.uniqBy(myArray, function(elem) { return JSON.stringify(_.pick(elem, [''a'', ''b''])); });

Tenga en cuenta que los objetos no son deterministas en cuanto al orden de las propiedades, por lo que es posible que desee limitarse al enfoque de matriz explícita.

PS Reemplaza uniqBy por uniq para Lodash <4


Hay una sugerencia en @voithos y @Danail respuesta combinada. Cómo resolví esto fue agregar una clave única a los objetos en mi matriz.

Datos de muestra de inicio

const animalArray = [ { a: 4, b: ''cat'', d: ''generic'' }, { a: 5, b: ''cat'', d: ''generic'' }, { a: 4, b: ''dog'', d: ''generic'' }, { a: 4, b: ''cat'', d: ''generic'' }, ];

En el ejemplo anterior, quiero que la matriz sea única por a y b pero ahora mismo tengo dos objetos que tienen a: 4 y b: ''cat'' . Al combinar a + b en una cadena, puedo obtener una clave única para verificar.

{ a: 4, b: ''cat'', d: ''generic'', id: `${a}-${b}` }. // id is now ''4-cat''

Nota: obviamente necesita mapear los datos o hacer esto durante la creación del objeto, ya que no puede hacer referencia a las propiedades de un objeto dentro del mismo objeto.

Ahora la comparación es simple ...

_.uniqBy(animalArray, ''id'');

La matriz resultante tendrá una longitud de 3 y habrá eliminado el último duplicado.


Utilice el método de Lodash con uniqWith :

_.uniqWith(array, [comparator])

Este método es como _.uniq excepto que acepta el comparator que se invoca para comparar elementos de la array . El orden de los valores de los resultados está determinado por el orden en que aparecen en la matriz. El comparador se invoca con dos argumentos: (arrVal, othVal) .

Cuando el comparator devuelve true , los elementos se consideran duplicados y solo la primera aparición se incluirá en la nueva matriz.

Ejemplo:
Tengo una lista de ubicaciones con latitude y longitude , algunas de las cuales son idénticas, y quiero ver la lista de ubicaciones únicas:

const locations = [ { name: "Office 1", latitude: -30, longitude: -30 }, { name: "Office 2", latitude: -30, longitude: 10 }, { name: "Office 3", latitude: -30, longitude: 10 } ]; const uniqueLocations = _.uniqWith( locations, (locationA, locationB) => locationA.latitude === locationB.latitude && locationA.longitude === locationB.longitude ); // Result has Office 1 and Office 2