[英]Iterate first x elements of an associative array
With an associative array of 12 elements; 具有12个元素的关联数组;
this.rolls = {1:[], 2:[], 3:[], 4:[], 5:[],
6:[], 7:[], 8:[], 9:[],10:[], 11:[], 12:[]};
what is the most effective way to get the sum of just the first 10 elements. 最有效的方法是获取前10个元素的总和。 The code below currently sums all elements;
下面的代码当前汇总所有元素;
var sum = 0;
for (var k in this.rolls) {
vals = this.rolls[k];
for (var i=0; i<vals.length; i++) {
sum += vals[i] || 0
};
};
this.score = sum
The first 10 elements being: 前10个元素是:
this.rolls = {1:[], 2:[], 3:[], 4:[], 5:[],
6:[], 7:[], 8:[], 9:[],10:[]};
Here is the full code: 这是完整的代码:
function Game() {
this.score = 0;
this.frameOver = false;
this.rolls = {1:[], 2:[], 3:[], 4:[], 5:[],
6:[], 7:[], 8:[], 9:[],10:[], 11:[], 12:[]};
this.currentFrame = 1;
// this.lastFrameStrike = false;
// this.lastFrameSpare = false;
// this.isStrike = false
};
Game.prototype.roll = function(pins) {
this.strikeOrSpare(pins);
this.bonusDistributor(pins);
this.rolls[this.currentFrame].push(pins);
this.scoreUpdater(pins);
this.frameHandler(pins);
this.nextFrameBonus(pins)
};
// --------------------------------------------------
Game.prototype.strikeOrSpare = function(pins) {
if (pins === 10) {
this.isStrike = true;
this.frameOver = true
}
else if (this.rolls[this.currentFrame][0] + pins === 10) {
this.isSpare = true;
this.frameOver = true
};
};
// --------------------------------------------------
Game.prototype.bonusDistributor = function(pins) {
if(this.wasSpare) { this.addToLastSpare(pins) };
if(this.wasStrike) { this.addToLast(pins) };
if(this.wasStrike2 && this.currentFrame > 1) { this.addToLastAgain(pins) };
};
// --------------------------------------------------
Game.prototype.addToLast = function(pins) {
this.rolls[this.currentFrame - 1][0] += pins
};
Game.prototype.addToLastAgain = function(pins) {
this.rolls[this.currentFrame - 2][0] += pins
};
Game.prototype.addToLastSpare = function(pins) {
this.rolls[this.currentFrame - 1][1] += pins;
this.wasSpare = false
};
// --------------------------------------------------
Game.prototype.scoreUpdater = function(pins) {
var sum = Object.keys(this.rolls).sort(function (a, b) {
return (+a) - (+b);
}).slice(0, 10).reduce(function (p, c) {
return p + this.rolls[c].reduce(function (p, c) {
return p + c;
}, 0);
}, 0);
};
Game.prototype.frameHandler = function(pins) {
if (this.frameOver) {
this.currentFrame++; this.frameOver = !this.frameOver
} else {
this.frameOver = !this.frameOver;
};
};
Game.prototype.nextFrameBonus = function(pins) {
if (this.isSpare) {
this.wasSpare = true;
this.isSpare = false
if (this.wasStrike) {
this.wasStrike = false;
this.wasStrike2 = true
}
} else if (this.isStrike && this.wasStrike) {
this.wasStrike2 = true
} else if (this.isStrike) {
this.isStrike = false;
this.wasStrike = true
} else if (this.wasStrike) {
this.wasStrike = false;
this.wasStrike2 = true
} else if (this.wasStrike2) {
this.wasStrike2 = false
};
};
// --------------------------------------------------
The first issue you'll have problems with is that this.rolls
is an Object
, not an Array
, so for (var k in this.rolls)
is not guaranteed to enumerate the keys in order. 您遇到的第一个问题是
this.rolls
是一个Object
,而不是Array
,因此不能保证 for (var k in this.rolls)
枚举键顺序。 So the first problem to solve is to take those first 10 keys, convert them to numbers, and sort them. 因此,要解决的第一个问题是获取前10个键,将其转换为数字,然后对其进行排序。 Here I'm using all native
Array
and Object
methods: 在这里,我使用所有本机
Array
和Object
方法:
var rolls = this.rolls;
var sum = Object
// Get all keys
.keys(rolls)
// Convert string keys to integers
.map(function (key) { return parseInt(key, 10); })
// Sort in ascending order
.sort()
// Take the first 10
.slice(0, 10)
// Get the arrays for each key
.map(function (key) { return rolls[key]; })
// Merge all arrays into one array
.reduce(function (allNumbers, array) { return allNumbers.concat(array); }, [])
// Sum all numbers
.reduce(function (sum, number) { return sum + (number || 0); }, 0);
Sort and filter object keys, then use them to reduce arrays to sums 对对象键进行排序和过滤,然后使用它们减少要求和的数组
var rolls = this.rolls;
var sum = Object.keys(rolls).sort(function (a, b) {
return (+a) - (+b);
}).slice(0, 10).reduce(function (p, c) {
return p + rolls[c].reduce(function (p, c) {
return p + c;
}, 0);
}, 0);
EDITED: There is one mistake in your example. 编辑:您的示例中有一个错误。 You cannot use this .
您不能使用此 。 rolls inside of
forEach
. 在
forEach
滚动 。 Declare it ( var self = this;
or my version is var rolls = this.rolls;
outside) 声明它(
var self = this;
或者我的版本是var rolls = this.rolls;
外)
I suggest following code for calculating sum: 我建议使用以下代码来计算总和:
var sum = 0;
var rolls = this.rolls;
Object.keys(rolls).forEach(function (key, i, array) {
if (i < 10) {
var item = rolls[key].slice();
while (item.length) {
sum += item ? Number(item.shift()) : 0 + item ? Number(item.pop()) : 0;
}
}
});
console.log(sum, this.rolls);
this.score = sum;
There is your full example: 有完整的示例:
function Game() { this.score = 0; this.frameOver = false; this.rolls = {1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [], 11: [], 12: []}; this.currentFrame = 1; // this.lastFrameStrike = false; // this.lastFrameSpare = false; // this.isStrike = false } Game.prototype.roll = function (pins) { this.strikeOrSpare(pins); this.bonusDistributor(pins); this.rolls[this.currentFrame].push(pins); this.scoreUpdater(pins); this.frameHandler(pins); this.nextFrameBonus(pins); }; // -------------------------------------------------- Game.prototype.strikeOrSpare = function (pins) { if (pins === 10) { this.isStrike = true; this.frameOver = true; } else if (this.rolls[this.currentFrame][0] + pins === 10) { this.isSpare = true; this.frameOver = true; } }; // -------------------------------------------------- Game.prototype.bonusDistributor = function (pins) { if (this.wasSpare) { this.addToLastSpare(pins); } if (this.wasStrike) { this.addToLast(pins); } if (this.wasStrike2 && this.currentFrame > 1) { this.addToLastAgain(pins); } }; // -------------------------------------------------- Game.prototype.addToLast = function (pins) { this.rolls[this.currentFrame - 1][0] += pins; }; Game.prototype.addToLastAgain = function (pins) { this.rolls[this.currentFrame - 2][0] += pins; }; Game.prototype.addToLastSpare = function (pins) { this.rolls[this.currentFrame - 1][1] += pins; this.wasSpare = false; }; // -------------------------------------------------- Game.prototype.scoreUpdater = function (pins) { var sum = 0; // var self = this; var rolls = this.rolls; Object.keys(rolls).forEach(function (key, i, array) { if (i < 10) { var item = rolls[key].slice(); while (item.length) { sum += item ? Number(item.shift()) : 0 + item ? Number(item.pop()) : 0; } } }); console.log(sum, this.rolls); this.score = sum; }; Game.prototype.frameHandler = function (pins) { if (this.frameOver) { this.currentFrame++; this.frameOver = !this.frameOver; } else { this.frameOver = !this.frameOver; } }; Game.prototype.nextFrameBonus = function (pins) { if (this.isSpare) { this.wasSpare = true; this.isSpare = false; if (this.wasStrike) { this.wasStrike = false; this.wasStrike2 = true; } } else if (this.isStrike && this.wasStrike) { this.wasStrike2 = true; } else if (this.isStrike) { this.isStrike = false; this.wasStrike = true; } else if (this.wasStrike) { this.wasStrike = false; this.wasStrike2 = true; } else if (this.wasStrike2) { this.wasStrike2 = false; } }; var game = new Game(); game.scoreUpdater();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.