2015-07-27 2 views
2

У меня есть многомерный массивсращивание нескольких массивов в многомерном массиве Javascript

[{id:0, type:1}, {id:1, type:1}, {id:2, type:2}] 

Я стремлюсь сделать, это удалить все 1-го типа и поэтому желаемый результат должен оставить id:2, type:2

tmpType = 1; 
for (var i in arr) { 
    if(arr[i].type == tmpType) { 
     arr.splice(i, 1); 
    } 
} 

Однако в цикл, из того, что я понимаю, будет трижды трижды, но каждый раз, когда я соединяюсь, цикл отличается. Это результат, который я получаю.

{{id:1, type:1}, {id:2, type:2}} 

Если у меня есть 3 вида типов: 1, у меня всегда будет последний в массиве.

+2

Ваш первый буквальным является недействительным синтаксис –

+1

Я думаю, лет u означало '[{id: 0, type: 1}, {id: 1, type: 1}, {id: 2, type: 2}]' вместо '{{id: 0, type: 1} , {id: 1, type: 1}, {id: 2, type: 2}} ' – saadq

ответ

3

В качестве splice изменений длина вам нужно либо переместить итератор, либо итерировать вниз.

Вы также должны использовать for, не for..in для перебора над составлять список присяжных заседателей

var arr = [{id:0, type:1}, {id:1, type:1}, {id:2, type:2}]; 

var type = 1, 
    i;         // OR // i = arr.length; 
for (i = arr.length - 1; i >= 0; --i) {   // while (i-- > 0) { 
    if (arr[i].type == type) { 
     arr.splice(i, 1); 
    } 
} 

arr; // [{"id": 2, "type": 2}] 

Других ответов предлагают использовать фильтр метода Массивов который является отличным альтернативным вариантом и вы можете найти его чище. Тем не менее, следует помнить, результат этих двух способов немного отличаются в этом случае будет модифицировать исходный массива ссылки («имеет побочные эффекты»), в то время как фильтр метод создаст совершенно новый экземпляр массива и оставить оригинал нетронутым.


Вы можете думать о фильтра как это, который также показывает, почему это немного дороже

function filter(arr, test) { 
    var i, 
     arr_out = []; 
    for (i = 0; i < arr.length; ++i) 
     if (i in arr && test(arr[i]) // invoking test each time is expensive 
      arr_out.push(arr[i]); 
    return arr_out; 
} 

splice может быть дорогим тоже, однако, как вы двигаетесь все indicies вокруг.

Самый дешевый способ сделать это без побочные эффекты (то есть оригинал, оставленный в покое) состоит в том, чтобы сделать сочетание двух; ручной for петля, которая push эсов к новому массива с амбулаторным тестом записываются в него, не вызывается отдельно

// arr as before 
var arr2 = [], 
    i; 
for (i = 0; i < arr.length; ++i) 
    if (arr[i].type === type) // doing our test directly, much cheaper 
     arr2.push(arr[i]); 
arr2; // desired array 

Для оригинального модифицированного простого варианта заключается в использовании метода splice я написал в начале этого ответ.
Другой вариант, чтобы скопировать оригинал, var arr2 = arr.slice(), затем опорожнить оригинал, arr.length = 0;, затем сделать последний цикл, который я показал, кроме как с arr и arr2 поменялись местами вокруг повторно заполнить arr

+0

Это то, что я хочу, но не могу его выписать. не знал о методе фильтра, есть ли разница в эффективности между вашим и фильтром? Мне понадобится оригинал, который будет затронут, так что это будет для этого метода. спасибо кучи. – vinz

+0

@vinz см. Edit :) –

+1

Если вы не имеете дело с массивами с более чем 10 000 предметов, вы никогда не заметите разницу в производительности. – jmar777

1

Если у вас есть реальный массив.

var data = [{id:0, type:1}, {id:1, type:1}, {id:2, type:2}] 
//Array has a method filter 
var filterdata = data.filter(function(element, index, array){ 
    return element.type == 2; 
}) 
//filterdata will contain an array of only objects that have type 2 
1

Вы должны цикл назад через массив. Использование циклов сплайсинга вперед означает, что вы пропустите элемент после того, как вы сращитесь на каждой итерации, теперь, когда он имеет тот же индекс, что и тот, который вы удалили.

var arr = [{id: 0, type: 1}, {id: 1, type: 1}, {id: 2, type: 2}]; 
for (var i = arr.length; i--;) { 
     if (arr[i].type === 1) arr.splice(i, 1); 
} 

Вы также можете сделать это:

var arr = [{id: 0, type: 1}, {id: 1, type: 1}, {id: 2, type: 2}]; 
arr = arr.filter(function (obj) { 
     return obj.type !== 1; 
}); 
1

Предполагая, что вы на самом деле имел в виду:

[{id:0, type:1}, {id:1, type:1}, {id:2, type:2}] 

Вы можете использовать filter:

var oldArr = [{id:0, type:1}, {id:1, type:1}, {id:2, type:2}]; 
var newArr = oldArr.filter(function(obj) { 
    return obj.type !== 1; 
}); 
Смежные вопросы