2012-11-13 23 views
5

我有一個數組充滿了正整數值,我怎麼能正常化這個列表,所以最大值總是100?先謝謝你!如何正常化JavaScript中的正數列表?

+4

[你有什麼嘗試?](http://whathaveyoutried.com/) – ruakh

+0

更具體。你對價值做什麼?繁殖/擺脫它們? 你是在一個比例之後,一個比例? –

+2

你將不得不在這裏更具體一些。如果你正在規範化***值,以便最大值縮小到正好等於100,那麼將該規模應用於所有其他數字是不會將它們保留爲整數。那麼你是否希望將最高的數字縮放到100,即使你有漂浮物,或者你想丟棄高於100的數字(過濾器)或者將所有大於100的數字夾緊到100,然後離開單獨休息(扭曲規模),還是你想做別的事情? – Norguard

回答

21

的想法是先找到你的數組中最大的數(使用applyMath.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)); 
+0

+1獲得詳細的答案。 – Shmiddty

+0

@wvxvw - 有趣。 [這是一個使用具有10,000個元素的'apply'進行的測試](http://jsfiddle.net/9HXv4/),它在所有主流瀏覽器中都完美無瑕地工作。我甚至在5款最新的IE瀏覽器(6-10)中測試過它。因爲[性能上的差異似乎傾向於'應用'](http://jsperf.com/math-max-apply-vs-loop),(在IE <9中,差異是*交錯*),I 'd建議堅持'apply'。 (注意:Firefox似乎正在使用一些瘋狂的巫術來實現循環方法中的異常性能,請參閱圖)。 –

+0

@wvxvw - 儘管你的循環實現並不是最有效的,但是使用你的循環並沒有改變很多:IE的老版本(可以說這些優化是最需要的)仍然支持'apply '由一個*大*的餘量。 –

0

那麼,您可以通過Math.max.apply(arr)獲得最大值,然後循環或使用arr.map將所有數字乘以100/max。完成。

4

像這樣

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); 
+2

我尊重你想要幫助,但你只是做了一些人爲他們工作。 :[記錄我不是-1。 – Snuffleupagus

+0

@Snuffleupagus - 以及所有其他答案? –

+2

我覺得'var arr = [101,5,6]'更簡單,更容易閱讀......只是說。 –

0

你需要找到的最大規模和數量都在目標範圍。

0
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; 
} 
0

只需編輯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; 
}