개체 속성으로 어레이에서 개체 제거
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
개체 속성을 일치시켜 배열에서 개체를 제거하려면 어떻게 해야 합니까?
네이티브 자바스크립트만 부탁드립니다.
삭제할 때마다 길이가 줄어들기 때문에 스플라이스 사용에 어려움을 겪고 있습니다.원본 인덱스에서 복제 및 스플라이싱을 사용하면 길이가 줄어드는 문제가 여전히 남아 있습니다.
당신이 사용한 것 같습니다.splice
이런 거요?
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
버그를 수정하기 위해 필요한 것은 감소입니다.i
다음 번에는 (뒤로 루프하는 것도 옵션입니다).
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
i--;
}
}
선형 시간 삭제를 방지하기 위해 배열 위에 유지할 배열 요소를 작성할 수 있습니다.
var end = 0;
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) === -1) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
또한 최신 런타임에서 선형 시간 조회를 방지하기 위해 해시 집합을 사용할 수 있습니다.
const setToDelete = new Set(listToDelete);
let end = 0;
for (let i = 0; i < arrayOfObjects.length; i++) {
const obj = arrayOfObjects[i];
if (setToDelete.has(obj.id)) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
멋진 기능으로 포장할 수 있습니다.
const filterInPlace = (array, predicate) => {
let end = 0;
for (let i = 0; i < array.length; i++) {
const obj = array[i];
if (predicate(obj)) {
array[end++] = obj;
}
}
array.length = end;
};
const toDelete = new Set(['abc', 'efg']);
const arrayOfObjects = [{id: 'abc', name: 'oh'},
{id: 'efg', name: 'em'},
{id: 'hij', name: 'ge'}];
filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));
console.log(arrayOfObjects);
만약 제자리에서 할 필요가 없다면, 그것은.Array#filter
:
const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));
다음과 같은 타사 리브를 사용하지 않고 해당 속성 중 하나로 항목을 제거할 수 있습니다.
var removeIndex = array.map(item => item.id).indexOf("abc");
~removeIndex && array.splice(removeIndex, 1);
로드/언더스코어 포함:
기존 어레이 자체를 수정하려면 스플라이스를 사용해야 합니다.다음은 findWhere of 언더스코어/lodash를 사용하여 보다 효과적이고 읽을 수 있는 방법입니다.
var items= [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'},
{id:'hij',name:'ge'}];
items.splice(_.indexOf(items, _.findWhere(items, { id : "abc"})), 1);
ES5 이상 포함
(로드/언더스코어 미포함)
ES5 이후에는findIndex
어레이에서 메소드를 사용하므로 로드/언더스코어 없이도 더 쉽습니다.
items.splice(items.findIndex(function(i){
return i.id === "abc";
}), 1);
(ES5는 거의 모든 최신 브라우저에서 지원됨)
지정된 배열의 ID를 기준으로 개체를 삭제합니다.
const hero = [{'id' : 1, 'name' : 'hero1'}, {'id': 2, 'name' : 'hero2'}];
//remove hero1
const updatedHero = hero.filter(item => item.id !== 1);
findIndex는 최신 브라우저에서 작동합니다.
var myArr = [{id:'a'},{id:'myid'},{id:'c'}];
var index = myArr.findIndex(function(o){
return o.id === 'myid';
})
if (index !== -1) myArr.splice(index, 1);
Set and ES5 필터를 사용하여 확인합니다.
let result = arrayOfObjects.filter( el => (-1 == listToDelete.indexOf(el.id)) );
console.log(result);
JsFiddle: https://jsfiddle.net/jsq0a0p1/1/ 입니다.
새 배열을 만들지 않고 기존 배열에서 제거하려면 다음을 시도하십시오.
var items = [{Id: 1},{Id: 2},{Id: 3}];
items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);
감소를 통해 역방향 루프 발생i
문제를 방지하기 위해:
for (var i = arrayOfObjects.length - 1; i >= 0; i--) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
또는 다음을 사용합니다.
var newArray = arrayOfObjects.filter(function(obj) {
return listToDelete.indexOf(obj.id) === -1;
});
네이티브 자바스크립트만 부탁드립니다.
ECMA스크립트 5에서 작업하는 보다 "기능적인" 대안 솔루션으로 다음을 사용할 수 있습니다.
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}]; // all that should remain
arrayOfObjects.reduceRight(function(acc, obj, idx) {
if (listToDelete.indexOf(obj.id) > -1)
arrayOfObjects.splice(idx,1);
}, 0); // initial value set to avoid issues with the first item and
// when the array is empty.
console.log(arrayOfObjects);
[ { id: 'hij', name: 'ge' } ]
ECMA-262의 'Array.prototype.reduceRight'의 정의에 따라,
reductRight는 호출된 개체를 직접 변환하지 않지만 콜백fn 호출에 의해 개체가 변환될 수 있습니다.
그래서 이것은 유효한 사용법입니다.reduceRight
.
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
당신의 대답은 이렇게 될 것입니다.특정 개체를 클릭하면 deleteme 함수에 대한 매개 변수의 인덱스를 클릭합니다.이 간단한 코드는 매력적으로 작동할 것입니다.
function deleteme(i){
if (i > -1) {
arrayOfObjects.splice(i, 1);
}
}
짧고 자체 설명적인 매개 변수를 좋아하거나 사용하지 않으려는 경우splice
간단한 필터를 사용하거나 저와 같은 SQL 사용자일 경우:
function removeFromArrayOfHash(p_array_of_hash, p_key, p_value_to_remove){
return p_array_of_hash.filter((l_cur_row) => {return l_cur_row[p_key] != p_value_to_remove});
}
사용 예는 다음과 같습니다.
l_test_arr =
[
{
post_id: 1,
post_content: "Hey I am the first hash with id 1"
},
{
post_id: 2,
post_content: "This is item 2"
},
{
post_id: 1,
post_content: "And I am the second hash with id 1"
},
{
post_id: 3,
post_content: "This is item 3"
},
];
l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 2); // gives both of the post_id 1 hashes and the post_id 3
l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 1); // gives only post_id 3 (since 1 was removed in previous line)
필터 & 인덱스 Of 포함
withLodash = _.filter(arrayOfObjects, (obj) => (listToDelete.indexOf(obj.id) === -1));
withoutLodash = arrayOfObjects.filter(obj => listToDelete.indexOf(obj.id) === -1);
필터 및 포함
withLodash = _.filter(arrayOfObjects, (obj) => (!listToDelete.includes(obj.id)))
withoutLodash = arrayOfObjects.filter(obj => !listToDelete.includes(obj.id));
사용할 수 있습니다.filter
이 메서드는 조건이 참이면 항상 요소를 반환합니다.따라서 id로 제거하려면 지정된 id와 일치하지 않는 모든 요소를 유지해야 합니다.다음은 예입니다.
arrayOfObjects = arrayOfObjects입니다.filter(obj = > obj.id != idToRemove)
잘못된 방법
우선, 다음과 같은 질문에 대한 답변을 제시합니다.filter
항목을 실제로 제거하지 않습니다.다음은 빠른 테스트입니다.
var numbers = [1, 2, 2, 3];
numbers.filter(x => x === 2);
console.log(numbers.length);
서에위는,numbers
어레이는 그대로 유지됩니다(아무것도 제거되지 않음).filter
된 새 합니다.x === 2
하지만 원래 배열은 그대로 남아 있습니다.
물론 이렇게 할 수 있습니다.
var numbers = [1, 2, 2, 3];
numbers = numbers.filter(x => x === 2);
console.log(numbers.length);
하만이단새어로할것레입다니당는하를에 새로운 배열을 입니다.numbers
.
배열에서 항목을 제거하는 올바른 방법
하나 이상의 올바른 방법은 다음과 같습니다.여기 예제에는 중복 항목이 의도적으로 포함되어 있으므로 중복 제거를 고려할 수 있습니다.
var numbers = [1, 2, 2, 3];
// Find all items you wish to remove
// If array has objects, then change condition to x.someProperty === someValue
var numbersToRemove = numbers.filter(x => x === 2);
// Now remove them
numbersToRemove.forEach(x => numbers.splice(numbers.findIndex(n => n === x), 1));
// Now check (this is obviously just to test)
console.log(numbers.length);
console.log(numbers);
이제 당신은 알아차릴 것입니다.length
숫자 1과 3만 배열에 남아 있음을 나타내는 2를 반환합니다.
당신의 경우에는
구체적으로 다음과 같은 질문에 답하기 위해:
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
정답은 다음과 같습니다.
listToDelete.forEach(x => arrayOfObjects.splice(arrayOfObjects.findIndex(n => n.id === x), 1));
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
var result = arrayOfObjects.filter(object => !listToDelete.some(toDelete => toDelete === object.id));
console.log(result);
언급URL : https://stackoverflow.com/questions/16491758/remove-objects-from-array-by-object-property
'programing' 카테고리의 다른 글
PowerShell에서 함수 오버로드 (0) | 2023.07.25 |
---|---|
PHP cURL GET 요청 및 요청 본문 (0) | 2023.07.25 |
키/값 JavaScript 개체의 키를 가져오는 방법 (0) | 2023.07.25 |
패키지에 파이썬 모듈의 이름을 나열하는 표준 방법이 있습니까? (0) | 2023.07.25 |
페르시아/아랍 숫자를 영어 숫자로 변환 (0) | 2023.07.25 |