拼接方法索引混淆

Posted

技术标签:

【中文标题】拼接方法索引混淆【英文标题】:splice method index confusion 【发布时间】:2021-12-23 08:21:27 【问题描述】:

我知道这听起来很有趣,因为我自己编写了解决方案,但是在一段时间没有看到它之后,我很难理解为什么它会起作用。该算法解决了 freecodecamp 的“库存更新”问题,尽管测试失败(比较并更新存储在 2D 数组中的库存与新交付的第二个 2D 数组。更新当前现有的库存项目数量(在 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' ] ]

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

非常感谢您的帮助

【问题讨论】:

我认为您不会收到我对答案所做的编辑的通知...并且由于您已经将其标记为已解决,我只想以这种方式提及,我只是添加了另一种解决方法我认为可能感兴趣的任务 【参考方案1】:

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

  let duplicates = [4, 6]

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

你正在为 in 而不是 of

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

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

第二个问题是,当您删除第一项时,第二项的索引会发生变化:-) 所以它不再是索引 6,而是现在 5。这可以通过在循环和拼接之前反转重复项来解决,所以首先从最高索引开始,然后删除“从头到尾”。

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

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);

【讨论】:

有趣的是,这个问题实际上要求您通过添加新库存的数量来更新当前库存重复项目,将新库存视为“交货”。我最终设计了一个比以前更简单的解决方案,但您的解决方案更加优雅,并且是一种很好的查看方式。很高兴您添加了评论

以上是关于拼接方法索引混淆的主要内容,如果未能解决你的问题,请参考以下文章

Splice 没有从给出的索引中拼接?

NSMutableArray 索引混淆

PyTorch: 张量的拼接切分索引

numpy 索引,切片 ,转置,变值,多个数组的拼接

python之字符串的索引,切片,分割,替换,去除指定字符,拼接,格式化

elastic search2.3.1 查询语句拼接实战