как удалить объект, отвечающий условию, из массива объектов? - PullRequest
0 голосов
/ 16 июня 2020

Я получаю в своей функции объект со следующей информацией

{
  "name": "Grand modèle",
  "description": "Par 10",
  "price": 0,
  "functional_id": "grand_modele_par_10",
  "quantity": 2,
  "amount": 0
}

, и мне нужно проверить следующий массив объектов, в котором он расположен, чтобы удалить его

[
  {
    "name": "Matériel crémation",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Sacs bordeaux",
        "description": "Pour les crémations Référence",
        "id": 12,
        "path": "",
        "items": [
          {
            "name": "Petit modèle",
            "description": "Par 25",
            "price": 0,
            "functional_id": "petit_modele_par_25",
            "quantity": 2,
            "amount": 0
          },
          {
            "name": "Grand modèle",
            "description": "Par 10",
            "price": 0,
            "functional_id": "grand_modele_par_10",
            "quantity": 2,
            "amount": 0,
            "itemAdded": false
          }
        ]
      }
    ]
  },
  {
    "name": "Documents",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Affiches procédure",
        "description": "De prise en charge",
        "id": 18,
        "path": "",
        "items": [
          {
            "price": 0,
            "functional_id": "affiches_procedure",
            "quantity": 1,
            "amount": 0
          }
        ]
      }
    ]
  }
]

Для этого я go просматриваю массив объектов с 'forEach', чтобы найти элемент, отвечающий условию равенства, и удалить его

public deleteItem(item) {


        this.fullCartInfo.forEach(category => {
            category.products.forEach(product => {
                product.items.forEach(itemAdded => {
                    if (item.functional_id === itemAdded.functional_id) {
                        this.fullCartInfo.splice(itemAdded);
                    }
                });
            });
        });
        this.cartService.removeItem(item);
    }


я получаю, чтобы он опустошил мои массив объектов. Как я могу заставить его удалить только того, кто соответствует условию? В чем моя ошибка? Всем спасибо за ваше время

1 Ответ

1 голос
/ 16 июня 2020

Array.prototype.splice(start[, deleteCount[, item1[, item2[, ...]]]]) ожидает индекс первого элемента, который должен быть удален (start) и, возможно, сколько элементов следует удалить (deleteCount).

Для start index, мы можем использовать второй аргумент обратного вызова Array.prototype.forEach(), который является индексом текущего элемента в коллекции.

В следующем примере используется:

  • сокращенный набор данных
  • обычная функция вместо вашего метода класса, просто потому, что с ней было легче работать. Вы можете просто скопировать и вставить тело функции в свой метод deleteItem.

const objectToRemove = { "functional_id": "grand_modele_par_10" }

const objects = {
  fullCartInfo: [
    { "products": [{ "id": 12, "items": [{ "functional_id": "grand_modele_par_10" }] }] },
    { "products": [{ "id": 18, "items": [{ "functional_id": "affiches_procedure" }] }] }
  ]
}

function deleteItem(item) {
  this.fullCartInfo.forEach((category, index) => {  // the index we will use for .splice() when we've found a matching category
    category.products.forEach(product => {
      product.items.forEach(itemAdded => {
        if (item.functional_id === itemAdded.functional_id) {
          this.fullCartInfo.splice(index, 1);  // remove one item only
        }
      });
    });
  });
}

deleteItem.apply(objects, [objectToRemove]);
// .apply() is only used to set the value of <this> in deleteItem and therefor simulate its behavior as a class method.

console.log(objects);

Но это будет работать только тогда, когда вы удалите только один элемент из коллекции или если вы удалите элементы с конца. В противном случае индекс .fullCartInfo.forEach(...) будет не синхронизирован c с фактической коллекцией, которую вы только что изменили с помощью .splice(). Например, вы удаляете первый элемент с индексом 0, тогда массив сдвинет все элементы на один индекс влево (элемент с индексом 1 будет тогда с индексом 0, элемент с индексом 2 будет в индексе 1, ... ), но индекс в обратном вызове не будет обновлен.

Если есть вероятность, что вы удалите несколько элементов, вам следует использовать .filter() или старый добрый for l oop, который повторяется из от последнего к первому.

.filter()

const objectToRemove = { "functional_id": "grand_modele_par_10" }

const objects = {
  fullCartInfo: [
    { "products": [{ "id": 12, "items": [{ "functional_id": "grand_modele_par_10" }] }] },
    { "products": [{ "id": 18, "items": [{ "functional_id": "affiches_procedure" }] }] }
  ]
}

function deleteItem(item) {
  this.fullCartInfo = this.fullCartInfo.filter((category, index) => {
    let keepCategory = true;
    
    category.products.forEach(product => {
      product.items.forEach(itemAdded => {
        if (item.functional_id === itemAdded.functional_id) {
          keepCategory = false;
        }
      });
    });
    
    return keepCategory;
  });
}

deleteItem.apply(objects, [objectToRemove]);
console.log(objects);

for l oop в обратном направлении

const objectToRemove = { "functional_id": "grand_modele_par_10" }

const objects = {
  fullCartInfo: [
    { "products": [{ "id": 12, "items": [{ "functional_id": "grand_modele_par_10" }] }] },
    { "products": [{ "id": 18, "items": [{ "functional_id": "affiches_procedure" }] }] }
  ]
}

function deleteItem(item) {
  for(let index = this.fullCartInfo.length - 1; index >= 0; index--) {
    this.fullCartInfo[index].products.forEach(product => {
      product.items.forEach(itemAdded => {
        if (item.functional_id === itemAdded.functional_id) {
          this.fullCartInfo.splice(index, 1);
        }
      });
    });
  }
}

deleteItem.apply(objects, [objectToRemove]);

console.log(objects);
...