我有一个填充了正整数值的数组,如何将此列表归一化,使最大值始终为100?谢谢!
我有一个填充了正整数值的数组,如何将此列表归一化,使最大值始终为100?谢谢!
这个想法是首先找出数组中最大的数字(使用apply
和Math.max
方法),然后计算该最大数字与100之间的比例。
接下来,只需要通过循环遍历你的数组并将所有数字除以该比例:
var numbers = [3, 8, 45, 74, 123],
ratio = Math.max.apply(Math, numbers) / 100,
l = numbers.length,
i;
for (i = 0; i < l; i++) {
numbers[i] = Math.round(numbers[i] / ratio);
}
这是示例代码:http://jsfiddle.net/XpRR8/
注意: 我使用Math.round
函数将数字四舍五入到最近的整数。如果你希望保留小数,只需删除该函数调用即可。
for ( i = 0; i < l; i++ ) {
numbers[i] /= ratio;
}
这里是示例链接:http://jsfiddle.net/XpRR8/1/
如果您不需要支持IE8及以下版本,则可以使用Array.prototype.map()
:
var numbers = [3, 8, 45, 74, 123],
ratio = Math.max.apply(Math, numbers) / 100;
numbers = numbers.map(function (v) {
return Math.round(v / ratio);
});
这里是代码片段:http://jsfiddle.net/XpRR8/2/
如果你支持IE8,但仍在使用jQuery,可以使用$.map()代替:
numbers = $.map(numbers, function (v) {
return Math.round(v / ratio);
});
这是代码片段:http://jsfiddle.net/XpRR8/3/
更新:如下方评论中@wvxvw所指出的,如果你担心某些边缘实现对apply
处理参数数目有人为限制,那么你可以使用循环代替Math.max.apply
。以下是一个例子(假设既不存在Array.prototype.map
,也不存在$.map
):
var numbers = [3, 8, 45, 74, 123],
ratio = 0,
i = numbers.length;
while (i--) numbers[i] > ratio && (ratio = numbers[i]);
ratio /= 100;
i = numbers.length;
while (i--) numbers[i] = Math.round(numbers[i] / ratio);
这里有一个示例代码:http://jsfiddle.net/XpRR8/4/
如果你正在使用ES6,这将变得非常简单:
var numbers = [3, 8, 45, 74, 123];
var ratio = Math.max(...numbers) / 100;
numbers = numbers.map(v => Math.round(v / ratio));
apply
测试10,000个元素的示例,在所有主流浏览器中都能完美运行;我甚至在5个最新的IE浏览器(6-10)中进行了测试。由于性能差异似乎倾向于apply
(在IE < 9中差异非常大),我建议坚持使用apply
。(顺便说一句:Firefox似乎正在使用一些疯狂的巫术来实现循环方法的异常性能。不解释)。 - Joseph Silberapply
。 - Joseph Silber像这样
function Normalize(array, value)
{
for( var i = 0, len = array.length; i < len; i++ )
{
if( parseInt(array[i]) > value) array[i] = value;
}
}
然后使用它:
var arr = [];
arr.push(101);
arr.push(5);
arr.push(6);
Normalize(arr,100);
var arr = [101, 5, 6]
更简单易读...只是这么说。 - Derek 朕會功夫function normalize(arr, max) {
// find the max value
var m = 0;
for(var x=0; x<arr.length; x++) m = Math.max(m, arr[x]);
// find the ratio
var r = max / m;
// normalize the array
for(var x=0; x<arr.length; x++) arr[x] = arr[x] * r;
return arr;
}
function normalize_array(arr) {
normalize = function(val, max, min) {
return(val - min) / (max - min);
}
max = Math.max.apply(null, arr)
min = Math.min.apply(null, arr)
hold_normed_values=[]
arr.forEach(function(this_num) {
hold_normed_values.push(normalize(this_num, max, min))
})
return(hold_normed_values)
}
例子:
nums = [10, 20, 30, 40, 50]
normalize_array(mums)
对LastCoder的代码进行编辑,以支持负数
function normalize(arr, max) {
// find the max value
var max = arr[0];
var min = arr[0];
for(var x=0; x<arr.length; x++)
max = Math.max(m, arr[x];
for(var x=0; x<arr.length; x++)
min = Math.min(m, arr[x];
// normalize the array
for(var x=0; x<arr.length; x++)
arr[x] = (arr[x] - min) / (max - min);
return arr;
}
你可以使用 Math.max.apply(arr)
获取最大值,然后通过循环或使用 arr.map
将所有数字乘以 100/max
。完成。