下划线:如何在排序后保留此数组的顺序?
Underscore: how to retain the order of this array after it's sorted?
我有以下数组:
var myNumbers = [70.37037037037037, 11.11111111111111, 11.11111111111111, 7.4074074074074066];
我需要对每个数字进行四舍五入,并将它们的总和合计为 100。如果它们不足,将按小数部分降序对项目加 1 来弥补差额。这称为 Largest Remainder Method
(我得到以下代码形式 How to make rounded percentages add up to 100%)。这是获取此内容的下划线代码:
var off = 100 - _.reduce(myNumbers, function(acc, x) {
return acc + Math.round(x)
}, 0);
var rounded_percentages = _.chain(myNumbers)
.sortBy(function(x) {
return Math.round(x) - x
})
.map(function(x, i) {
return Math.round(x) + (off > i) - (i >= (myNumbers.length + off))
})
.value();
结果是:
[8, 70, 11, 11]
效果很好,但顺序未保留。如何在保留顺序或使用对象而不是数组执行整个操作并保留正确的键映射的同时实现上述目标?
在保留顺序的情况下,结果应该是:
[70, 11, 11, 8]
有了键映射,初始变量看起来像:
var myNumbers = {
firstNum: 70.37037037037037,
secondNum: 11.11111111111111,
thirdNum: 11.11111111111111,
fourthNum: 7.4074074074074066
};
结果将是:
{
fourthNum: 8,
firstNum: 70,
secondNum: 11,
thirdhNum: 11
};
根本不要改变数组的顺序。只创建一个排列(一个索引数组,然后按每个索引指向的数组值的 属性 排序),然后在上面运行你的算法。
var rounded_percentages = _.map(myNumbers, Math.floor);
var off = _.reduce(rounded_percentages, function(acc, x) { return acc - x; }, 100);
var permutation = _.sortBy(_.map(myNumbers, function(_, i) { return i; }), function(i) {
return rounded_percentages[i] - myNumbers[i]; // those with the largest diff first
});
for (var i=0; i<off; i++)
rounded_percentages[permutation[i]]++
这是 最大余数法 的更接近实现,您的实现中的 Math.round
很奇怪。
我有以下数组:
var myNumbers = [70.37037037037037, 11.11111111111111, 11.11111111111111, 7.4074074074074066];
我需要对每个数字进行四舍五入,并将它们的总和合计为 100。如果它们不足,将按小数部分降序对项目加 1 来弥补差额。这称为 Largest Remainder Method
(我得到以下代码形式 How to make rounded percentages add up to 100%)。这是获取此内容的下划线代码:
var off = 100 - _.reduce(myNumbers, function(acc, x) {
return acc + Math.round(x)
}, 0);
var rounded_percentages = _.chain(myNumbers)
.sortBy(function(x) {
return Math.round(x) - x
})
.map(function(x, i) {
return Math.round(x) + (off > i) - (i >= (myNumbers.length + off))
})
.value();
结果是:
[8, 70, 11, 11]
效果很好,但顺序未保留。如何在保留顺序或使用对象而不是数组执行整个操作并保留正确的键映射的同时实现上述目标?
在保留顺序的情况下,结果应该是:
[70, 11, 11, 8]
有了键映射,初始变量看起来像:
var myNumbers = {
firstNum: 70.37037037037037,
secondNum: 11.11111111111111,
thirdNum: 11.11111111111111,
fourthNum: 7.4074074074074066
};
结果将是:
{
fourthNum: 8,
firstNum: 70,
secondNum: 11,
thirdhNum: 11
};
根本不要改变数组的顺序。只创建一个排列(一个索引数组,然后按每个索引指向的数组值的 属性 排序),然后在上面运行你的算法。
var rounded_percentages = _.map(myNumbers, Math.floor);
var off = _.reduce(rounded_percentages, function(acc, x) { return acc - x; }, 100);
var permutation = _.sortBy(_.map(myNumbers, function(_, i) { return i; }), function(i) {
return rounded_percentages[i] - myNumbers[i]; // those with the largest diff first
});
for (var i=0; i<off; i++)
rounded_percentages[permutation[i]]++
这是 最大余数法 的更接近实现,您的实现中的 Math.round
很奇怪。