在匹配值并满足条件的 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
}
}
}
}
}
我正在查看散列映射和接口,但我不太确定如何在此处应用它。如果有任何替代方法可以使上述操作更快,我将不胜感激。
编辑:
这里引起危险的是你有 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
次,这是一个巨大的进步。
作为奖励,它的代码更少,更易于阅读!
所以我在尝试构建一个快于 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
}
}
}
}
}
我正在查看散列映射和接口,但我不太确定如何在此处应用它。如果有任何替代方法可以使上述操作更快,我将不胜感激。
编辑:
这里引起危险的是你有 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
次,这是一个巨大的进步。
作为奖励,它的代码更少,更易于阅读!