Reputation: 1167
I have an array filled with positive int values, how could I normalize this list so the max value is always 100? Thank you in advance!
Upvotes: 9
Views: 30730
Reputation: 13334
Pass your array into the following function:
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)
}
Example:
nums = [10, 20, 30, 40, 50]
Usage:
normalize_array(mums)
Upvotes: 1
Reputation: 219938
The idea is to first find the highest number in your array (using apply
on Math.max
), then find the ratio between that highest number and 100.
After that, it's just a matter of looping through your array and dividing all your numbers by that ratio:
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);
}
Here's the fiddle: http://jsfiddle.net/XpRR8/
Note: I'm using Math.round
to round the numbers to the nearest integer. If you instead prefer to keep them as floats, just remove the function call:
for ( i = 0; i < l; i++ ) {
numbers[i] /= ratio;
}
Here's the fiddle: http://jsfiddle.net/XpRR8/1/
If you don't have to support IE8 and below, you can use 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);
});
Here's the fiddle: http://jsfiddle.net/XpRR8/2/
If you do support IE8, but are anyhow using jQuery, you can use $.map()
instead:
numbers = $.map(numbers, function (v) {
return Math.round(v / ratio);
});
Here's the fiddle: http://jsfiddle.net/XpRR8/3/
Update: As pointed out by @wvxvw in the comments below, if you're concerned about fringe implementations that impose an artificial limit on the amount of arguments apply
will handle, then use a loop instead of Math.max.apply
. Here's an example (assuming neither Array.prototype.map
nor $.map
are available):
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);
Here's the fiddle: http://jsfiddle.net/XpRR8/4/
If you're using ES6, this becomes laughably simple:
var numbers = [3, 8, 45, 74, 123];
var ratio = Math.max(...numbers) / 100;
numbers = numbers.map(v => Math.round(v / ratio));
Upvotes: 32
Reputation: 7347
Just an edit to LastCoder code to support Negative numbers as well
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;
}
Upvotes: 0
Reputation: 21086
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;
}
Upvotes: 1
Reputation: 143099
You need to find the maximum and scale all numbers to the target range.
Upvotes: 0
Reputation: 82287
Like this
function Normalize(array, value)
{
for( var i = 0, len = array.length; i < len; i++ )
{
if( parseInt(array[i]) > value) array[i] = value;
}
}
And then use it:
var arr = [];
arr.push(101);
arr.push(5);
arr.push(6);
Normalize(arr,100);
Upvotes: 4
Reputation: 324650
Well, you can get the maximum value with Math.max.apply(arr)
, then either loop through or use arr.map
to multiply all numbers by 100/max
. Done.
Upvotes: 0