Удаление элемента массива со сращиванием, если значение (я) истинно - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь удалить отмеченные элементы, которые являются истинными, из массива с помощью метода array.splice. Кажется, он работает большую часть времени, но по некоторым причинам бывают случаи, когда проверяются два или три элемента, и только один элемент удаляется из проверенного списка, когда я запускаю функцию, которая склеивает элементы массива.

Я попытался отобразить массив и вернуть новый массив с удаленными объединенными элементами, вроде работает, но не всегда. Я сопоставляю массив с двумя аргументами (индекс и элемент). Я создаю оператор if, который, если элемент проверен или выполнен, удалить его с помощью (index, 1). После этого я возвращаю новый массив. Проблема возникает в функции removeCheckedBeer

  // if there is no item string, create an empty array
  const items = JSON.parse(localStorage.getItem('items')) || []

  function addItem(e) {
    // prevent the form from submitting
    e.preventDefault()
    const text = (this.querySelector('[name=item]')).value
    const item = {
      text,
      done: false
    }
    items.push(item)
    // rerenders list without having to reload the page
    populateList(items, itemsList)
    localStorage.setItem('items', JSON.stringify(items))
    this.reset()
  }

  // function removes all items in the array
  const removeAllItems = e => {
    e.preventDefault()
    items.splice(0)
    localStorage.setItem('items', JSON.stringify(items))
    populateList([], itemsList)
  }

  // remove all checked items
  const removeCheckedBeer = e => {
    e.preventDefault()
    items.map((item, index) => {
      if (item.done === true) {
        console.log(index, item)
        items.splice(index, 1)
      }
      return items
    })
    localStorage.setItem('items', JSON.stringify(items))
    populateList(items, itemsList)
  }

  // toggle a single item
  const toggleDone = e => {
    if (!e.target.matches('input')) return // skip this unless it's an input
    const el = e.target
    const index = el.dataset.index
    // toggle from done to !done
    items[index].done = !items[index].done
    localStorage.setItem('items', JSON.stringify(items))
  }

  // toggle inventory of all items to true or false
  const toggleAllItems = e => {
    items.forEach((item, index, array) => {
      e.target.name === 'checkAll' ? (items[index].done = true) : (items[index].done = false)
  console.log(e.target.name)
})
localStorage.setItem('items', JSON.stringify(items))
populateList(items, itemsList)
  }

  const populateList = (beers = [], beerList) => {
    // map through the array, and create a new array to render the beer list
    beerList.innerHTML = beers.map((beer, i) => {
      return `
        <li>
          <input type="checkbox" data-index=${i} id="item${i}" 
${beer.done ? 'checked' : ''} />
          <label for="item${i}">${beer.text}</label>
        </li>
      `
    }).join('')
  }

Итак, я ожидаю, что количество проверенных элементов будет удалено из массива, начиная с индекса первого проверенного элемента. В результате элемент удаляется, но иногда по одному элементу за раз. Иногда удаляется более одного элемента. Может кто-нибудь объяснить, что происходит с моей функцией?

1 Ответ

0 голосов
/ 15 января 2019

Проблема с splice() заключается в том, что элемент, удаленный из массива, также сдвигает все остальные элементы на один. Было бы лучше использовать filter():

items = items.filter(e => e.done !== true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...