#javascript #arrays #loops
#javascript #массивы #циклы
Вопрос:
Я пытаюсь создать функцию, которая удаляет элемент из массива. И массив, и элемент настраиваются с использованием параметров, вводимых при вызове функции.
Однако он не возвращает ожидаемое [1,2,4], скорее, он возвращает «еще нет» строку, которую я встроил в статус if, чтобы вернуть в случае сбоя.
Я вижу в журнале консоли всплывающую переменную = 3, и текущий цикл for корректно перебирает все параметры. Так почему же это не работает?
const removeFromArray = function() {
let args = Array.from(arguments);
let popped = args.pop();
for (i = 0; i < args.length; i ) {
let current = args[i];
if (current === popped) {
console.log(args);
return args;
} else {
console.log("not yet");
}
}
};
removeFromArray([1, 2, 3, 4], 3);
Комментарии:
1. Вы окажете себе услугу, если сделаете правильный отступ в своем коде.
2. почему бы просто не использовать indexOf / splice?
3. Почему вы просто не объявляете свои параметры в заголовке функции? Обратите внимание, что массив, который вы передали в качестве первого аргумента, находится в
arguments[0]
. Вы туда не смотрите. Вы, кажется, думаете, чтоarguments
в нем много записей, в том числе из массива, который вы передаете, но в нем есть только две записи: (вложенный) массив и значение.4. В вашем примере аргументы. длина будет равна 1, потому что после удаления 3 остается только один аргумент (массив). Я думаю, вы имели в виду перебор аргументов [0], а не аргументов.
5. поскольку ваш цикл for перебирает первый аргумент в arguments , который является массивом,
for (i = 0; i < [[1,2,3,4]].length; i )
поэтому сравнениеif ([1,2,3,4] ===3)
Ответ №1:
Хорошо, я прокомментировал ваш код, проблемы в нем и внес соответствующие изменения, чтобы он работал так, как вы хотели:
const removeFromArray = function()
{
// arguments is not [1, 2, 3, 4, 3], but instead it's [[1, 2, 3, 4], 3] (length is 2, remember this later)
let args = Array.from(arguments);
// pop works correctly and returns 3
let popped = args.pop();
// here we cannot loop with args.length, as it is 2
// if we change args.length to args[0].length, this will work
for (i = 0; i < args[0].length; i ) {
// args[i] won't work here for the same reason args.length didn't work,
// because we're targeting a wrong thing
// if we change this to args[0][i], it will work
let current = args[0][i];
// After the changes, this if will work correctly
if (current === popped) {
// We can't just return args
// A) we're once again targeting and wrong thing
// B) we haven't removed anything yet
// so lets change this to first splice the array (remove the wanted value)
args[0].splice(i, 1);
// and then return the array where the wanted value is removed
return args[0];
}
}
};
const newArray = removeFromArray([1, 2, 3, 4], 3);
// output the returned new array where 3 is removed
console.log(newArray)
Основная проблема заключается в том, что args
он не содержит того, что вы думали, что он делает (массив чисел), args[0]
на самом деле это так.
Другое дело, что когда вы находили значение, которое хотели удалить из массива, вы на самом деле никогда его не удаляли. Итак, здесь мы используем splice, чтобы фактически удалить значение перед возвратом.
Комментарии:
1. Большое спасибо, действительно ценю все комментарии. Это имеет смысл, как вы сказали, основная проблема заключалась в том, что длина аргументов составляла 2, а не 5, поэтому остальная часть кода не работала.
2. Нет проблем! Обратите внимание, что действительно есть лучшие способы реализовать что-то подобное, как показали другие, но никогда не помешает попробовать что-то по-своему. Я хотел показать, как вы могли бы заставить эту конкретную реализацию работать правильно 🙂
Ответ №2:
const removeFromArray = function (array, itemToRemove) {
return array.filter(item => item !== itemToRemove);
};
Комментарии:
1. Спасибо, не могли бы вы объяснить это мне? Функции со стрелками для меня новы. Кажется, возвращает другую функцию, которая говорит, что если элемент (где это объявлено?) не совпадает со вторым параметром, то фильтруйте его?
2. Конечно! Функция со стрелкой проста. const func = (item) => item != 3 совпадает с функцией func (item) { return item != true ;} Метод ‘filter’ массивов вызывает функцию для каждого из элементов. Если функция возвращает true, то этот элемент остается в массиве. Мы также могли бы написать что-то вроде этого array.filter(function (item) { return item != 3; });
Ответ №3:
Я не знаю, почему вы не используете какие-либо встроенные функции JS, такие как
let removeFromArray = (arr, remove) => arr.filter(x => x != remove)
let filteredArray = removeFromArray([1, 2, 3, 4], 3)
Но давайте сделаем это по-вашему
const removeFromArray(arr, remove) {
const items = [];
for (const item of arr) {
if (item != remove) items.push(item)
}
return items;
};
removeFromArray([1, 2, 3, 4], 3);
Комментарии:
1. Спасибо. Я работал с PHP и сделал перерыв…
Ответ №4:
Вот как я бы это сделал, поскольку вы сказали, что хотите изменить исходный массив, а не создавать новый, splice
было бы правильным инструментом для использования.
function removeFromArray(arr, rem){
while(~arr.indexOf(rem)){
arr.splice(arr.indexOf(rem), 1);
}
}
var arr = [1, 2, 3, 4, 3];
removeFromArray(arr, 3)
console.log(arr);