Удалить элемент из вложенного массива в Javascript по значению ключа - PullRequest
0 голосов
/ 02 марта 2020

У меня есть такой объект:

{
  "id": 1,
  "name": "first",
  "sections": [
    {
      "id": 1,
      "title": "First section",
      "contents": [
        {
          "id": "123",
          "title": "Sample title 1",
          "description": "<html>code</html>",
        },
        {
          "id": "124",
          "title": "Sample title 2",
          "description": "<html>code</html>"
        },
        {
          "id": "125",
          "title": "Some other sample",
          "description": "<html>code</html>"
        }
      ]
    },
    {
      "id": 2,
      "title": "Second section",
      "contents": [
        {
          "id": "126",
          "title": "Sample title 126",
          "description": "<html>code</html>"
        },
        {
          "id": "127",
          "title": "Sample title 127",
          "description": "<html>code</html>"
        }
      ]
    }
  ]
}

Я хочу удалить указанный c объект из массива содержимого по его идентификатору (все эти идентификаторы уникальны).

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

obj.sections.forEach(function(section) {
    section.contents.forEach((content) => {
        if (content.id == 125) {
            console.log(content)
            console.log(section)
        }
    })
})

В приведенном выше коде console.log (section) возвращает undefined. Как я могу получить позицию в массиве разделов, который содержит массив содержимого, который имеет специфицированный c идентификатор Например, id: 125 вернул бы позиции секций 0, так что я могу использовать сплайс для удаления этого элемента.

Если мой подход совершенно неверный, пожалуйста, укажите мне правильное направление, спасибо:)

Ответы [ 3 ]

2 голосов
/ 02 марта 2020

Вы можете использовать .filter() вместо .splice(). .filter() сохранит все предметы, за которые вы вернули true, и отбросит те, за которые вы вернули false. Таким образом, если объект содержимого текущего раздела имеет id, равный тому, который вы хотите удалить, вы можете вернуть false, чтобы удалить его, в противном случае вернуть true, чтобы сохранить этот элемент. Вы можете использовать это с .map() для отображения каждого объекта раздела на новый с обновленным массивом содержимого:

const obj = { "id": 1, "name": "first", "sections": [ { "id": 1, "title": "First section", "contents": [ { "id": "123", "title": "Sample title 1", "description": "<html>code</html>", }, { "id": "124", "title": "Sample title 2", "description": "<html>code</html>" }, { "id": "125", "title": "Some other sample", "description": "<html>code</html>" } ] }, { "id": 2, "title": "Second section", "contents": [ { "id": "126", "title": "Sample title 126", "description": "<html>code</html>" }, { "id": "127", "title": "Sample title 127", "description": "<html>code</html>" } ] } ] };

const idToRemove = 125;
obj.sections = obj.sections.map(
  sec => ({...sec, contents: sec.contents.filter(({id}) => id != idToRemove)})
);

console.log(obj);
.as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore */
2 голосов
/ 02 марта 2020

Почему бы не использовать простой фильтр для выполнения задачи. Кроме того, это будет намного более чистый и неизменный способ сделать это.

let newArrWithoutContentWithGivenId = obj.sections.map(section =>
     ({...section, contents: section.contents.filter(content => 
         content.id != 125)}));

Здесь мы сопоставляем каждый раздел, содержимое которого не содержит идентификатор 125. Короче говоря, section > content.id != 125 будет удалено из новый массив.

Надеюсь, это поможет:)

Примечание: код не проверен, он просто поможет вам найти способ сделать это чисто.

1 голос
/ 02 марта 2020

Вам нужно использовать только второй аргумент forEach:)

obj.sections.forEach(function(section, sectionIndex) {
    section.contents.forEach((content, contentIndex) => {
        if (content.id == 125) {
            // use the sectionIndex and contentIndex to remove
        }
    })
})
...