2017-02-11 2 views
0

Я прочитал несколько вопросов об этом на StackOverflow и нашел некоторые решения даже, но все они, кажется, делают то же самое странное дело:Попытка удалить элементы из массива в JavaScript/JQuery

У меня есть массив (массив A) 8 имен:

arrayA= ["person1", "person2", "person3", "person4", "person5", "person6", "person7", "person8"]; 

И у меня есть массив (массив B) 1 имя:

arrayB= ["person1"]; 

Теперь я хочу, чтобы удалить все имена, которые не делают встречаются в массиве B, от Array A.

Итак, я написал небольшую функцию, которая пересекает все элементы в массиве A и проверяет, встречаются ли они в массиве B. Если они этого не делают, я удаляю их из Array A.

Итак, я искал функцию для удаления строк из массива (в PHP это намного проще ...), и я нашел несколько методов, которые все дают мне точно такую ​​же проблему. В приведенном ниже примере, я выбрал самый чистый метод, с помощью JQuery в $ .grep:

arrayA= ["person1", "person2", "person3", "person4", "person5", "person6", "person7", "person8"]; 
 
arrayB= ["person1"]; 
 

 
for (var i = 0, len = arrayA.length; i < len; i++) { 
 
\t \t \t 
 
    if($.inArray(arrayA[i], arrayB) == -1){ 
 

 
    var removeName= arrayA[i]; 
 

 
    console.log('Removing row of: ' + removeName); 
 

 
    /* 
 
    $('tr[player=\'' + removeName + '\']').find('td') 
 
    .wrapInner('<div style="display: block;" />') 
 
    .parent() 
 
    .find('td > div') 
 
    .slideUp(700, function(){ 
 
     $(this).parent().parent().remove(); 
 
    }); 
 
    */ 
 

 
    arrayA= $.grep(arrayA, function(value) { 
 
     return value != removeName; 
 
    }); 
 
    
 
    console.log('arrayA now consists of: ' + arrayA); 
 

 
    } 
 

 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Как вы можете видеть, это только удаляет «даже» элементы из Arraya, т.е. «PERSON2» , "person4", "person6" и "person8".

Если я выполняю эту функцию несколько раз, второй раз он снова удаляет только «четные» элементы (теперь это «person3» и «person7»), и в третий раз он удаляет «person5» (наконец) ...

Может кто-нибудь, пожалуйста, скажите мне, что я не вижу? Вы можете видеть из журнала консоли, что, в первый раз запустить его, все «нечетные» элементы в массиве (т.е. person3, person5 и person7) являются «неопределенными» ...

+0

Что цель использования 'for' цикл? Требуется ли удалить элементы из исходного массива или вернуть новый массив, содержащий только элементы, находящиеся в 'arrayB'? – guest271314

+1

Вы переиндексируете (или фактически заменяете) массив во время его итерации. Другими словами, когда вы удаляете один, следующий индекс становится текущим, и поэтому он пропускается, когда цикл переходит к следующему элементу. –

+0

Да, я догадался, что это было нечто подобное.Не могли бы вы предоставить мне решение удалить все элементы из массива A, которые * не * встречаются в массиве B сразу, без необходимости перебирать их и удалять их по одному? –

ответ

2

Вы можете использовать do..while петля, Array.prototype.splice() для удаления элементов из массива

arrayA= ["vincent" 
 
     , "Rumpelstilzchen" 
 
     , "LuckeR" 
 
     , "Nordland" 
 
     , "Siegfried" 
 
     , "NeKrone" 
 
     , "Carnage" 
 
     , "tom59fr"]; 
 
arrayB= ["vincent"]; 
 

 
var i = 0; 
 

 
do { 
 
    if (arrayB[0] !== arrayA[i]) { 
 
    arrayA.splice(i, 1); 
 
    } else { 
 
    ++i; 
 
    } 
 
} while (i < arrayA.length); 
 
delete i; 
 

 
console.log(arrayA, arrayB);

+0

Прохладный! Это действительно работает! Благодаря комментарию @squint мне удалось заставить его работать, запустив мой цикл for-loop назад, чтобы предотвратить смещение индекса массива, который заставил бы его пропускать каждый элемент «четный»: 'for (var i = arrayA.length-1; i> = 0; i--) {' Но это более элегантно. Благодаря! –

1

Это происходит потому, что при вызове этого:

arrayA= $.grep(arrayA, function(value) { 
    return value != removeName; 
}); 

Длина массива А изменяется, поэтому arrayA[k] переместится в положение arrayA[k-1] (когда k> i).

Итак, мы должны создать новый массив для хранения отфильтрованных элементов и после итерации дать его значение arrayA.

arrayA= ["person1", "person2", "person3", "person4", "person5", "person6", "person7", "person8"]; 
 
arrayB= ["person1","person4"]; 
 
var arrayC=[]; 
 
for (var i = 0, len = arrayA.length; i < len; i++) { 
 
    console.log('inArray:'+$.inArray(arrayA[i], arrayB)) 
 
    if($.inArray(arrayA[i], arrayB) != -1){ 
 
    arrayC.push(arrayA[i]); 
 
    } 
 
    console.log('arrayC now consists of: ' + arrayC); 
 
} 
 
arrayA=arrayC;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

+0

Спасибо! Мне удалось предотвратить смещение индексов, перейдя через массив назад (начиная с 'var i = arrayA.length-1' и спустившись с' i - ', но ваше решение тоже классно! –

Смежные вопросы