lodash에 JavaScript 컬렉션의 항목을 대체하는 더 간단한 방법이 있는지 궁금합니다. (가능한 중복 이지만 거기에 대한 답변을 이해하지 못했습니다 🙂
나는 그들의 문서를 보았지만 아무것도 찾을 수 없었다
내 코드는 다음과 같습니다
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);
});
업데이트 :
교체하려는 객체에는 다음과 같은 많은 속성이 있습니다.
{id : 1, Prop1 : …, Prop2 : … 등}
해결책:
dfsq 덕분에 lodash 내에서 제대로 작동하는 것처럼 보이고 꽤 깔끔한 적절한 솔루션을 찾았 으며이 요구 사항을 여러 곳에서 보냈으므로 믹스 인에 넣었습니다. 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));
더 빠른 솔루션
@dfsq에서 지적했듯이 다음은 더 빠릅니다.
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);
}
};
답변
귀하의 경우 배열에서 객체를 찾고 Array.prototype.splice()
메소드를 사용 하기 만하면 됩니다 . 자세한 내용은 여기를 참조 하십시오 .
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Find item index using _.findIndex (thanks @AJ Richardson for comment)
var index = _.findIndex(arr, {id: 1});
// Replace item at index using native splice
arr.splice(index, 1, {id: 100, name: 'New object.'});
// "console.log" result
document.write(JSON.stringify( arr ));
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
답변
가장 간단한 솔루션은 ES6 .map
또는 lodash 를 사용하는 것처럼 보입니다 _.map
.
var arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
// lodash
var newArr = _.map(arr, function(a) {
return a.id === 1 ? {id: 1, name: "Person New Name"} : a;
});
// ES6
var newArr = arr.map(function(a) {
return a.id === 1 ? {id: 1, name: "Person New Name"} : a;
});
이것은 원래 배열을 변경하지 않는 좋은 효과가 있습니다.
답변
[ES6] 이 코드는 저에게 효과적입니다.
let result = array.map(item => item.id === updatedItem.id ? updatedItem : item)
답변
function findAndReplace(arr, find, replace) {
let i;
for(i=0; i < arr.length && arr[i].id != find.id; i++) {}
i < arr.length ? arr[i] = replace : arr.push(replace);
}
이제 모든 방법에 대한 성능을 테스트 해 보겠습니다.
답변
findIndex 및 pick을 사용하여 동일한 결과를 얻을 수도 있습니다.
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
var data = {id: 2, name: 'Person 2 (updated)'};
var index = _.findIndex(arr, _.pick(data, 'id'));
if( index !== -1) {
arr.splice(index, 1, data);
} else {
arr.push(data);
}
답변
시간이 지남에 따라 데이터 변이를 피하고 작은 단일 책임 기능을 작성하는보다 기능적인 접근 방식을 수용해야합니다. ECMA 스크립트 (6) 표준을 사용하면 제공과 자바 스크립트에서 함수형 프로그래밍 패러다임을 즐길 수있는 map
, filter
및 reduce
방법. 다른 기본, 밑줄 또는 가장 기본적인 작업을 수행 할 다른 작업이 필요하지 않습니다.
아래에는 다른 언어 기능을 사용하여이 문제를 해결하는 방법을 보여주기 위해이 문제에 대한 제안 된 솔루션이 포함되어 있습니다.
ES6 맵 사용 :
const replace = predicate => replacement => element =>
predicate(element) ? replacement : element
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const predicate = element => element.id === 1
const replacement = { id: 100, name: 'New object.' }
const result = arr.map(replace (predicate) (replacement))
console.log(result)
재귀 버전-매핑과 동일합니다.
const replace = predicate => replacement =>
{
const traverse = ([head, ...tail]) =>
head
? [predicate(head) ? replacement : head, ...tail]
: []
return traverse
}
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const predicate = element => element.id === 1
const replacement = { id: 100, name: 'New object.' }
const result = replace (predicate) (replacement) (arr)
console.log(result)
최종 배열의 순서가 중요하지 않은 object
경우 HashMap 데이터 구조 로 사용할 수 있습니다 . 이미 키 컬렉션을 키로 사용하는 경우 매우 편리합니다. object
그렇지 않으면 먼저 표현을 변경해야합니다.
객체 레스트 스프레드 , 계산 된 속성 이름 및 Object.entries가 필요 합니다 .
const replace = key => ({id, ...values}) => hashMap =>
({
...hashMap, //original HashMap
[key]: undefined, //delete the replaced value
[id]: values //assign replacement
})
// HashMap <-> array conversion
const toHashMapById = array =>
array.reduce(
(acc, { id, ...values }) =>
({ ...acc, [id]: values })
, {})
const toArrayById = hashMap =>
Object.entries(hashMap)
.filter( // filter out undefined values
([_, value]) => value
)
.map(
([id, values]) => ({ id, ...values })
)
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const replaceKey = 1
const replacement = { id: 100, name: 'New object.' }
// Create a HashMap from the array, treating id properties as keys
const hashMap = toHashMapById(arr)
console.log(hashMap)
// Result of replacement - notice an undefined value for replaced key
const resultHashMap = replace (replaceKey) (replacement) (hashMap)
console.log(resultHashMap)
// Final result of conversion from the HashMap to an array
const result = toArrayById (resultHashMap)
console.log(result)
답변
당신은 단지 하나의 속성, lodash를 교체하려는 경우 _.find
와 _.set
충분해야한다 :
var arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
_.set(_.find(arr, {id: 1}), 'name', 'New Person');