在匹配值并满足条件的 3 个数组之间迭代的更快方法?打字稿

Faster way to iterate between 3 arrays who match values and meet conditions? typescript

所以我在尝试构建一个快于 20 秒的 excel sheet 时遇到了麻烦。我正在使用下面的方法比较 3 个不同的数组,然后打印出我需要的答案。

for (let i = 0; i < this.arrayNumberOne[0].length; i++) {
    let orangeOne = this.arrayNumberOne[0][i]['item_1'];
    let orangeTwo = this.arrayNumberOne[0][i]['item_2'];
    let orangeThree = orangeOne.concat(orangeTwo)

    for (let k = 0; k < this.arrayNumberTwo[0].length; k++) {
        let appleOne = this.arrayNumberTwo[0][k]['item_1'];
        
        for (let j = 0; j < this.arrayNumberThree[0].length; j++) {
            let grapeOne = this.arrayNumberThree[0][j]['item_1'];
            let grapeTwo = this.arrayNumberThree[0][j]['item_2'];
            let grapeThree = this.arrayNumberThree[0][j]['item_3'];
        
            if (orangeThree == grapeOne && appleOne == grapeTwo) {

                if (grapeThree == null || grapeThree == '') {
                    // print to response to excel
                }

                else if (grapeThree == 'sells') {
                    //  print stuff to excel
                }

                else if (grapeThree == 'buys') {
                    // print stuff to excel
                }
            }
        }
    }
}

我正在查看散列映射和接口,但我不太确定如何在此处应用它。如果有任何替代方法可以使上述操作更快,我将不胜感激。

编辑:

Playground Link

这里引起危险的是你有 3 个嵌套循环,但你的数据是二维的,所以你预计最多有 2 个嵌套循环(一个用于 X,一个用于 Y)。你要关注的是获取每个单元格的值的过程应该尽可能快,因为这是需要发生最多次数的事情。

这里的关键是预处理您的值(电子表格单元格中的内容,buy/sell/blank),以便快速查找这些值。

例如:

// Index all actions by player id and item name
const indexedActions: {
    [playerId: string]: {
        [itemCatName: string]: string
    }
} = {}

// Loop through all actions once to index them.
for (const {playerId, itemCatName, action} of actions) {
    if (!indexedActions[playerId]) indexedActions[playerId] = {}
    indexedActions[playerId][itemCatName] = action
}

运行后您将获得如下数据:

{
    "12": {
        "potionsmall-potion": 'buy'
        // etc...
    }
    // etc...
}

这很重要,因为现在查找任何单元格都非常简单:

indexedActions[playerId][itemName]

这可以让您完全删除最内层的循环。

// Loop through items
for (let i = 0; i < items.length; i++) {
    let itemCat = items[i]['itemCategory']
    let itemNam = items[i]['itemName']
    let combineCat = itemCat.concat(itemNam)
    
    // Loop through players
    for (let k = 0; k < players.length; k++) {
        let playerIdentify = players[k]['playerId']
        
        // Lookup what this player did with this item
        const actionToDo = indexedActions[playerIdentify][combineCat]

        // do stuff with action
    }
}

优化前

  • 每一项
    • 对于每个玩家
      • 对于每个动作
        • doLogic()

这里“doLogic”被执行itemCount * playerCount * actionCount次。

优化后

  • 对于每个动作
    • 索引每个动作
  • 每一项
    • 对于每个玩家
      • doLogic()

现在我们在前面做了更多的工作,但是 doLogic 只执行了 itemCount * playerCount 次,这是一个巨大的进步。

作为奖励,它的代码更少,更易于阅读!

See playground