для l oop пропуск одного элемента в массиве в javascript - PullRequest
3 голосов
/ 06 августа 2020

Я пытаюсь создать функцию, которая удаляет строки из массива, если они включают символ в определенном другом списке

Вот код:

var possible = ["salutations", "goodbye", "thanks", "welcome"];
var incorrect = ["o"];

console.log(possible);

function narrowdown(possible, incorrect)
{
    var templist = possible;
    for (i in possible)
    {   
        console.log(i + " " + possible[i]);
        var array1 = possible[i].split("");
        var common = array1.filter(value => incorrect.includes(value));
        console.log(common)
        if (common.length)
        {
            templist.splice(i, 1);
        }
    }
    possible = templist;
}

narrowdown(possible, incorrect);

console.log(possible);

Здесь я пытаюсь чтобы удалить все слова, содержащие букву o. Я создал временный массив в функции, потому что раньше со мной случалось, что a for l oop полностью пропускает элементы. Код сначала регистрирует индекс элемента в списке, а затем сам элемент.

Затем он превращает слово в массив и проверяет совпадение между ним и «неправильным» массивом. Он делает это правильно и регистрирует перекрывающиеся символы. Проблема вроде бы в том, что он почему-то пропускает пункт "до свидания". Он даже не обрабатывает его.

Вот результат, который я получаю:

[ 'salutations', 'goodbye', 'thanks', 'welcome' ]
0 salutations
[ 'o' ]
1 thanks
[]
2 welcome
[ 'o' ]
[ 'goodbye', 'thanks' ]

Ответы [ 4 ]

2 голосов
/ 06 августа 2020

Прежде всего, for (i in possible) - плохой способ перебора массива, поскольку он извлекает ключи до начала l oop и никогда не обновляет этот список ключей. Кроме того, если кто-то присваивает массиву атрибут, например possible.foo = 17, тогда ваш l oop также будет go через это. Проблема, с которой вы столкнулись, заключается в том, что когда вы объединяете массив, все остальное смещается на единицу влево, меняя их индексы на единицу меньше, поэтому ваш новый индекс фактически пропускает следующий элемент. Исправление заключается в использовании стандартного для l oop и уменьшении i после склейки:

for (let i = 0; i < possible.length; i ++) {
    // more code...
    if (common.length) {
        templist.splice(i, 1);
        i --;
    }
}
0 голосов
/ 06 августа 2020

Проблема возникает из-за строки tempList = possible, которая является назначением по ссылке, что означает, что когда вы выполняете операцию splice , вы делаете это на обоих массивах одновременно.

Обычно считается дурным тоном манипулировать такими данными, вы должны иметь narrowDown, возвращающее значение, которое вы повторно назначаете possible, вместо того, чтобы фильтровать их на месте. Если вы это сделаете, вы также можете использовать некоторые из новых методов массива:

var possible = ["salutations", "goodbye", "thanks", "welcome"];
var incorrect = ["o"];

function narrowdown(possible, incorrect)
{
    return possible.filter(item => !incorrect.some(test => item.includes(test)))
}

possible = narrowdown(possible, incorrect);

console.log(possible);

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

0 голосов
/ 06 августа 2020

Если вы ищете менее «императивную» версию этой функции, вы можете использовать Array.filter(), Array.some() и * 1008. *, чтобы сделать однострочную функцию, которая выполняет трюк (для целей форматирования я разделил ее на несколько строк в приведенном ниже фрагменте).

const possible = ['salutations', 'goodbye', 'thanks', 'welcome'];

function narrowDown(possible, incorrect) {
    return possible.filter((value) => (
        !incorrect.some((exclude) => (value.includes(exclude)))
    ));
}

console.log('["o"]', JSON.stringify(narrowDown(possible, ['o'])));
console.log('["a"]', JSON.stringify(narrowDown(possible, ['a'])));
console.log('["a", "o"]', JSON.stringify(narrowDown(possible, ['a', 'o'])));
0 голосов
/ 06 августа 2020

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

var possible = ["salutations", "goodbye", "thanks", "welcome"];
var incorrect = ["o"];

console.log(possible);

function narrowdown(possible, incorrect)
{
    var templist = possible;
    var i = possible.length;
    while (i--)
    {   
        console.log(i + " " + possible[i]);
        var array1 = possible[i].split("");
        var common = array1.filter(value => incorrect.includes(value));
        console.log(common)
        if (common.length)
        {
            templist.splice(i, 1);
        }
    }
    possible = templist;
}

narrowdown(possible, incorrect);

console.log(possible);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...