拼接法指数混乱

splice method index confusion

我知道这听起来很有趣,因为我自己编写了解决方案,但在一段时间未看到它后,我很难理解为什么它会起作用。该算法解决了 freecodecamp 的“库存更新”问题,尽管测试失败(将二维数组中存储的库存与新鲜交付的第二个二维数组进行比较和更新。更新当前现有的库存项目数量(在 arr1 中)。如果找不到商品,则将新的商品和数量添加到库存数组中。返回的库存数组应按商品的字母顺序排列。)算法如下:

function updateInventory(arr1, arr2) {
    let newInv = [...arr1, ...arr2]
    //create single list of items only from both arrays
    let temp = newInv.flat().filter(item => typeof item === 'string')
    //create list of the index of all duplicate items
    let duplicates = temp.reduce((acc, item, index) => {
        if (temp.indexOf(item) != index){
            acc.push(index)
        }
        return acc
    }, [])
    //remove duplicate items
    for (let index in duplicates) {
        newInv.splice(index, 1)

    }
    //sort by alphabetical order
    newInv.sort((a,b) => {
        return a[1] > b[1] ? 1 : -1
    })
    return newInv
}
// Example inventory lists
var curInv = [
    [21, "Bowling Ball"],
    [2, "Dirty Sock"],
    [1, "Hair Pin"],
    [5, "Microphone"]
];

var newInv = [
    [2, "Hair Pin"],
    [3, "Half-Eaten Apple"],
    [67, "Bowling Ball"],
    [7, "Toothpaste"]
];

updateInventory(curInv, newInv);

据我了解预期结果应该是:

[ [ 21, 'Bowling Ball' ],
  [ 2, 'Dirty Sock' ],
  [ 1, 'Hair Pin' ],
  [ 3, 'Half-Eaten Apple' ],
  [ 5, 'Microphone' ],
  [ 7, 'Toothpaste' ] ]

然而,得到的是:

[ [ 67, 'Bowling Ball' ],
  [ 2, 'Dirty Sock' ],
  [ 2, 'Hair Pin' ],
  [ 3, 'Half-Eaten Apple' ],
  [ 5, 'Microphone' ],
  [ 7, 'Toothpaste' ] ]

这是要删除的重复元素对。我确定我可能遗漏了一些简单的东西,但我就是不明白。

非常感谢您的帮助

有两个问题。第一个是 for 循环

  let duplicates = [4, 6]

  for (let index in duplicates) {
        newInv.splice(index, 1)
    }

您正在为 in 而不是 of

in 遍历索引(in 就像 in index..!:)), for 高于值
如果在循环中记录索引,您将看到 0,1 = 重复元素的索引
将其更改为 for 然后它是 4,6 = 重复元素的值 = 要删除的项目的索引。另一种选择是

duplicates.forEach(i => newInv.splice(i, 1))

第二个问题是,当你删除第一个项目时,第二个项目的索引改变了:-) 所以它不再是索引 6,而是现在的 5。这可以通过在循环和拼接之前反转重复项来解决, 所以首先从最高索引开始并删除 'from end to start'.

所以这应该给出请求的结果

function updateInventory(arr1, arr2) {
    let newInv = [...arr1, ...arr2]
      //create single list of items only from both arrays
    let temp = newInv.flat().filter(item => typeof item === 'string')
      //create list of the index of all duplicate items
    let duplicates = temp.reduce((acc, item, index) => {
        if (temp.indexOf(item) != index) {
          acc.push(index)
        }
        return acc
      }, []).reverse()
      //remove duplicate items
    for (let index of duplicates) {
      newInv.splice(index, 1)
    }
    //sort by alphabetical order
    newInv.sort((a, b) => {
      return a[1] > b[1] ? 1 : -1
    })
    return newInv
  }

  // Example inventory lists
var curInv = [
  [21, "Bowling Ball"],
  [2, "Dirty Sock"],
  [1, "Hair Pin"],
  [5, "Microphone"]
];

var newInv = [
  [2, "Hair Pin"],
  [3, "Half-Eaten Apple"],
  [67, "Bowling Ball"],
  [7, "Toothpaste"]
];


let result = updateInventory(curInv, newInv);

console.log(result);

这就是我解决作业的方法

function updateInventory(curInv, newInv) {
    newInv.forEach(newItem => {
      let newItemName = newItem[1]      
      let inCurrent = curInv.find(currItem => currItem[1] === newItemName)
      if(!inCurrent) curInv.push(newItem)
    })
    return curInv.sort((a,b) => a[1].localeCompare(b[1]))
  }  

  // Example inventory lists
var curInv = [
  [21, "Bowling Ball"],
  [2, "Dirty Sock"],
  [1, "Hair Pin"],
  [5, "Microphone"]
];

var newInv = [
  [2, "Hair Pin"],
  [3, "Half-Eaten Apple"],
  [67, "Bowling Ball"],
  [7, "Toothpaste"]
];


let result = updateInventory(curInv, newInv);

console.log(result);