Это просто упражнение в курсе, это приложение выбирает случайный фрукт из массива фруктов, а затем функция removeItem() должна удалить его из массива и вернуть измененный массив, но я получаю странный вывод, и функция не работает.
Проблема видна здесь
function randomFruit(importedArray) {
let random = Math.floor(Math.random() * importedArray.length);
return importedArray[random];
}
function removeItem(importedArray, item) {
for (let i = 0; i < importedArray.length; i++) {
if (importedArray[i] === item) {
importedArray.splice(i, 1);
return [...importedArray.slice(0, i), ...importedArray.slice(i + 1)];
} else {
return "not found";
}
}
}
function makeFruitArray() {
var foods = ["?", "?", "?", "?", "?"];
return foods;
}
let fruitArray = makeFruitArray();
let fruitItem = randomFruit(fruitArray);
let remaining = removeItem(fruitArray, fruitItem);
console.info({fruitArray, fruitItem, remaining});извините, я изменил это ?
Вы должны объяснить по-английски, в чем заключается проблема: «Когда срывают вишню, кажется, что арбуз также удаляется из списка». Постарайтесь свести к минимуму работу, которую должны будут выполнить другие, просматривая ваш вопрос.
Спасибо за совет, я учусь и учту это, когда буду задавать вопросы в будущем?
Обратите внимание, что ваш вопрос не имеет ничего общего с React. Я добавил живой пример, который вы можете использовать, демонстрирующий ваш неработающий код. Вы всегда должны удалять любой код, который не связан с проблемой
Пожалуйста, попробуйте написать заголовок, который поможет отличить ваш вопрос от других подобных вопросов на этом сайте.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В функции removeItem есть две проблемы:
Если случайный элемент не является первым элементом в массиве, функция возвращает not found. Он вообще не будет работать для второго цикла, так как ваша функция возвращает not found после первой итерации.
Метод splice обновляет исходный массив. Пока вы передаете fruitArray методу removeItem, он передается как ссылка, и его обновление внутри функции с использованием splice также обновит фактический массив.
Самый простой и безопасный способ удаления элемента из массива -
function removeItem(importedArray, item) {
const filteredArray = importedArray.filter((each) => each !== item);
if (filteredArray.length === 0) return 'Not Found';
return filteredArray;
}
Возникнет проблема, если есть два элемента одного типа (значения).
Почему вы предлагаете не использовать сплайсинг? Использование фильтра для удаления элемента может привести к сканированию всего массива, даже если он находит совпадение в первом элементе. Нет необходимости в тесте include, не так ли? Есть много ненужной работы.
@RonHillel Судя по вопросу и коду ОП, не похоже, что будет два элемента одного типа.
@JuanMendes ты прав. Это было не самое эффективное решение. Я обновил его. Это, скорее всего, решит проблемы, которые вы упомянули.
@himayan Он все еще страдает от проблемы, которую вы на самом деле упомянули ? Вы изменяете массив, который вы использовали для отображения полного списка, вы можете создать новый массив, распространяя массив, как вы предлагали ранее. Я просто сказал, что вы не объяснили, почему они не должны изменять массив на месте (из-за ошибки, которую я только что упомянул)
@JuanMendes Я тоже запутался. filter кажется лучшим способом сделать это. includes был ненужным.
Как сказал химайан, проблема заключалась в том, что сращивание уже изменяет массив.
Вот мое решение:
function removeItem(importedArray, item) {
for (let i = 0; i < importedArray.length; i++) {
if (importedArray[i] === item) {
importedArray.splice(i, 1);
break;
}
}
return importedArray;
}
Но если вы измените массив, то отображение существующего массива будет нарушено...
Это в области функции, а не в области приложения. После этого функции не требуется запись исходного массива.
Ему это нужно, он также отображает исходный массив. Я сделал ваш код работоспособным, чтобы вы могли увидеть, как он не работает.
:) Это работает. Он не отображает массив в области функции removeItem...
@RonHillel importedArray — это ссылка на исходный массив; это изменяет исходный массив. Вот почему ОП распространялся на новый массив.
Вы запутались, не имеет значения, локальная переменная или глобальная. И глобальные, и локальные переменные могут указывать на один и тот же массив.
Ваша функция удаления элемента работает неправильно. Вместо того, чтобы писать циклы и объединять массив для создания нового, вы должны просто использовать метод filter
function removeItem(importedArray, item) {
let newArray = importedArray.filter(function (element) {
return element !== item;
});
return newArray;
}
да, немного медленно, так как нет необходимости сканировать весь массив, но работает
@JuanMendes Не могли бы вы объяснить, почему это решение работает медленнее?
Я думаю, это потому, что я сканирую весь массив, который имеет сложность n. Там может быть лучший способ сделать это.
Да, потому что, если вы используете обычный цикл for, вы можете выйти из цикла, как только найдете свой элемент, тогда как filter будет продолжать перебирать весь массив.
Было две основные проблемы:
for в removeItem всегда возвращался на первой итерации.Я также удалил весь ненужный код, используемый для воспроизведения вашей проблемы. Прочтите Как спросить, чтобы убедиться, что вы помогаете другим помогать вам.
function randomFruit(importedArray) {
let random = Math.floor(Math.random() * importedArray.length);
return importedArray[random];
}
function removeItem(importedArray, item) {
for (let i = 0; i < importedArray.length; i++) {
if (importedArray[i] === item) {
// Don't modify the original array since we want to
// display the original fruits
return [...importedArray.slice(0, i), ...importedArray.slice(i + 1)];
}
}
// Error condition goes outside the loop, not inside.
return null;
}
function makeFruitArray() {
var foods = ["?", "?", "?", "?", "?"];
return foods;
}
let fruitArray = makeFruitArray();
let fruitItem = randomFruit(fruitArray);
let remaining = removeItem(fruitArray, fruitItem);
console.info({fruitArray, fruitItem, remaining});
Пожалуйста, разместите вывод здесь в виде текста, а не ссылок на изображения, чтобы нам было легче понять, что «не так».