У меня есть массив, который содержит несколько отдельных элементов и несколько массивов:

var groceries = ["toothpaste", ["plums", "peaches", "pineapples"], ["carrots", "corn", "green beans"], "orange juice", ["chocolate", "ice cream"], "paper towels", "fish"];

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

Для отдельных элементов я написал эту функцию:

function removeItems(arr, item) {
  for ( var i = 0; i < item.length; i++ ) {
    var index = arr.indexOf(item[i]);
    if (index > -1) {
      arr.splice(index, 1);
    }
  }
};

Итак, я могу позвонить:

removeItems(groceries, ["fish", "orange juice"]);

И это работает именно так, как я хочу. Однако я не могу понять, как сделать так, чтобы функция также могла удалять массивы (например, ["шоколад", "мороженое"]) из большего массива. Как бы я пошел об этом?

1
sprucegoose 27 Авг 2017 в 10:46

3 ответа

Лучший ответ

Используйте Array # Reduce для создания словаря ключей. Если элемент является массивом, объедините все значения, чтобы создать ключ. Затем отфильтруйте все элементы, сгенерировав одинаковые ключи и проверив их по словарю.

Примечание. Фильтр Array # создает новый массив и не меняет исходный массив.

var groceries = ["toothpaste", ["plums", "peaches", "pineapples"], ["carrots", "corn", "green beans"], "orange juice", ["chocolate", "ice cream"], "paper towels", "fish"];

function removeItems(arr, toRemove) {
  function createKey(item) {
    return Array.isArray(item) ? item.join('-') : item;
  }

  var removeDict = toRemove.reduce(function(d, item) {
    var key = createKey(item);
    
    d[key] = true;
    
    return d;
  }, {});

  return arr.filter(function(item) {
    var key = createKey(item);
    
    return !removeDict[key];
  });
}

var result = removeItems(groceries, ["fish", "orange juice", ["chocolate", "ice cream"]]);

console.log(result);
4
Ori Drori 27 Авг 2017 в 08:20

Вот что я бы сделал:

const groceries = [
    "toothpaste",
    ["plums", "peaches", "pineapples"],
    ["carrots", "corn", "green beans"],
    "orange juice",
    ["chocolate", "ice cream"],
    "paper towels",
    "fish"
];

const equals = (x, y) => JSON.stringify(x) === JSON.stringify(y);

const removeItems = (xs, ys) => xs.filter(x => !ys.some(y => equals(x, y)));

const result = removeItems(groceries, [
    "fish",
    "orange juice",
    ["chocolate", "ice cream"]
]);

console.log(result);

Сначала мы определяем, что означает, что два значения равны. Далее мы определяем removeItems, используя это равенство значений. Мы говорим: оставьте все те x, которые не равны ни y.

0
Aadit M Shah 27 Авг 2017 в 08:25

В таких задачах, как удаление элементов из темы, я стараюсь избегать использования методов функционального массива, поскольку они будут повторяться в соответствии с начальным количеством элементов, даже если вы начнете удалять элементы. Так что мое решение было бы весьма обязательным;

function remover(itemToDelete, items){
  var i       = 0,
      check   = false;
  
  for (var item of items){
    check = Array.isArray(item) ? item.includes(itemToDelete)
                                : item === itemToDelete;
    check ? items.splice(i,1)
          : i++;
  }
  return items;
}

var groceries = ["toothpaste", ["plums", "peaches", "pineapples"], ["carrots", "corn", "green beans"], "orange juice", ["chocolate", "ice cream"], "paper towels", "fish"];

console.log(remover("chocolate", groceries));
console.log(remover("fish", groceries));
0
Redu 27 Авг 2017 в 08:09