Me pregunto si hay un método más simple en lodash para reemplazar un elemento en una colección de JavaScript. (Posible duplicado pero no entendí la respuesta allí :)
Miré su documentación pero no pude encontrar nada
Mi código es:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Can following code be reduced to something like _.XX(arr, {id:1}, {id:1, name: "New Name"});
_.each(arr, function(a, idx){
if(a.id === 1){
arr[idx] = {id:1, name: "Person New Name"};
return false;
}
});
_.each(arr, function(a){
document.write(a.name);
});
Actualización: el objeto con el que intento reemplazar tiene muchas propiedades como
{id: 1, Prop1: ..., Prop2: ..., y así sucesivamente}
Solución:
Gracias a dfsq, pero encontré una solución adecuada dentro de lodash que parece funcionar bien y es bastante ordenada, y también la puse en un mixin ya que tengo este requisito en muchos lugares. JSBin
var update = function(arr, key, newval) {
var match = _.find(arr, key);
if(match)
_.merge(match, newval);
else
arr.push(newval);
};
_.mixin({ '$update': update });
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
_.$update(arr, {id:1}, {id:1, name: "New Val"});
document.write(JSON.stringify(arr));
Solución más rápida Como señaló @dfsq, seguir es mucho más rápido
var upsert = function (arr, key, newval) {
var match = _.find(arr, key);
if(match){
var index = _.indexOf(arr, _.find(arr, key));
arr.splice(index, 1, newval);
} else {
arr.push(newval);
}
};
javascript
lodash
Vishal Seth
fuente
fuente
_.findIndex
para el partido._.findIndex
lugar de_.find
te permitirá soltar tanto el segundo_.find
como el_.indexOf
. Estás iterando a través de la matriz 3 veces cuando todo lo que necesitas es 1.Respuestas:
En su caso, todo lo que necesita hacer es encontrar el objeto en la matriz y usar el
Array.prototype.splice()
método, lea más detalles aquí :fuente
indexOf
que será muy rápida (utilizará los navegadores nativos Array.prototype.indexOf). Pero de todos modos, me alegra que encuentre una solución que funcione para usted._.findIndex
? Entonces no necesitas usar_.indexOf
.Parece que la solución más simple sería usar ES6
.map
o lodash_.map
:Esto tiene el buen efecto de evitar la mutación de la matriz original.
fuente
[ES6] Este código funciona para mí.
fuente
updatedItem
matriz si no incluye un elemento con el mismoid
.Ahora probemos el rendimiento para todos los métodos:
Mostrar fragmento de código
fuente
También puede usar findIndex y pick para lograr el mismo resultado:
fuente
A medida que pasa el tiempo, debe adoptar un enfoque más funcional en el que debe evitar las mutaciones de datos y escribir pequeñas funciones de responsabilidad única. Con el estándar ECMAScript 6, se puede disfrutar paradigma de programación funcional en JavaScript con los previstos
map
,filter
yreduce
métodos. No necesita otro lodash, guión bajo o qué más hacer para hacer las cosas más básicas.A continuación, he incluido algunas soluciones propuestas para este problema con el fin de mostrar cómo se puede resolver este problema utilizando diferentes características del lenguaje:
Usando el mapa ES6:
Versión recursiva - equivalente de mapeo:
Requiere desestructuración y dispersión de la matriz .
Cuando la orden de la matriz final no es importante que se puede utilizar una
object
como un HashMap estructura de datos. Muy útil si ya tiene una colección con clave comoobject
, de lo contrario, primero debe cambiar su representación.Requiere propagación de reposo de objetos , nombres de propiedades calculados y entradas de objeto .
fuente
Si solo está tratando de reemplazar una propiedad, lodash
_.find
y_.set
debería ser suficiente:fuente
Si el punto de inserción del nuevo objeto no necesita coincidir con el índice del objeto anterior, entonces la forma más simple de hacer esto con lodash es usar
_.reject
y luego introducir nuevos valores en la matriz:Si tiene varios valores que desea reemplazar en una sola pasada, puede hacer lo siguiente (escrito en formato que no sea ES6):
fuente
Usando la función lodash unionWith, puede realizar una inserción simple a un objeto. La documentación indica que si hay una coincidencia, usará la primera matriz. Envuelva su objeto actualizado en [] (matriz) y colóquelo como la primera matriz de la función de unión. Simplemente especifique su lógica de coincidencia y, si la encuentra, la reemplazará y, si no, la agregará
Ejemplo:
fuente
No está mal la variante también)
fuente
fuente
Si está buscando una manera de cambiar de manera inmutable la colección (como estaba cuando encontré su pregunta), puede echar un vistazo a inmutability-helper , una biblioteca bifurcada de la utilidad React original. En su caso, lograría lo que mencionó a través de lo siguiente:
fuente
Puedes hacerlo sin usar lodash.
fuente
Inmutable , adecuado para
ReactJS
:Asumir:
El elemento actualizado es el segundo y el nombre se cambia a
Special Person
:Sugerencia : el lodash tiene herramientas útiles, pero ahora tenemos algunas de ellas en Ecmascript6 +, así que solo uso la
map
función que existe en amboslodash
yecmascript6+
:fuente
Encontré esto también y lo hizo simplemente de esa manera.
Si lo desea podemos generalizarlo
fuente