2012-08-10 23 views
2

我想知道如何在更清潔和最佳的方式做到這一點:的Javascript,重複的對象鍵N倍,爲N其值

我有具有以下結構的對象:

{ 
    "125": 2, 
    "439": 3, 
    "560": 1, 
    "999": 2, 
    ... 
} 

我想創建一個重複每個鍵的平面數組,它的值表示的次數。和轉換鍵(字符串)爲整數的獎勵點。在這個例子中,結果數組應該是:

[ 125, 125, 439, 439, 439, 560, 999, 999 ] 

我試過了幾種方法,但他們都看起來過度設計。肯定有一個更簡單的方法。 這是我和下劃線了(並返回一個字符串數組,也不是整數):

_.compact(_.flatten(_.map(files, function(num, id) { 
    return new Array(num+1).join('$'+id).split('$') 
}))) 

我知道有很多方法可以做到這一點。我只想要一個乾淨而快捷的方式。作爲一個紅寶石開發商也可能是一樣簡單:提前

> files = {"125" => 2, "439" => 3, "560" => 1, "999" => 2} 
=> {"125"=>2, "439"=>3, "560"=>1, "999"=>2} 
> files.map {|key, value| [key.to_i] * value}.flatten 
=> [125, 125, 439, 439, 439, 560, 999, 999] 

感謝。

回答

1

試試這個:

var obj = { 
    "125": 2, 
    "439": 3, 
    "560": 1, 
    "999": 2 
} 

var arr = []; 

for (prop in obj) { 
    for (var i = 0; i < obj[prop]; i++) 
     arr.push(parseInt(prop)); 
} 
1

我知道這是普通的JavaScript,但比你發佈的代碼似乎更清潔對我說:

var dict = { 
    "125": 2, 
    "439": 3, 
    "560": 1, 
    "999": 2 
} 
var result = []; 

for(key in dict) 
    for(i = 0; i < dict[key]; i++) 
     result.push(key * 1); 

alert(result); 
0

嗯......不知道如果我在拿到,但也許是這樣的:

var myObj = { 
    "125": 2, 
    "439": 3, 
    "560": 1, 
    "999": 2 
}, 
myArray = []; 

for(k in myObj){ 
    for(i = 0; i < myObj[k]; i++){ 
     myArray.push(k); 
    } 
} 
console.log(myArray) 
+0

正確的,只是他想的整數,所以你應該添加值,之前使用'parseInt函數()'或類似的東西陣列。 – jeff 2012-08-10 17:44:04

0

這些方法是否更清潔是相當主觀的:

// some helper function for creating an array with repeated values 
function repeat(val, times) { 
    var arr = []; 
    for(var i = 0; i < times; i = arr.push(val)); 
    return arr; 
} 

function convert(obj) { 
    var result = [], key; 
    for(key in obj) { 
     result = result.concat(repeat(+key, obj[key])); 
    } 
    return result; 
} 

還是更注重功能的做法:

Object.keys(obj).reduce(function(result, key) { 
    return result.concat(repeat(+key, obj[key])); 
}, []); 

// with underscore.js 
_.reduce(_.keys(obj), function(result, key) { 
    return result.concat(repeat(+key, obj[key])); 
}, []); 
+1

'push'返回新的長度,所以我認爲你需要在每次迭代中將'obj [k]'添加到'l'。 – zzzzBov 2012-08-10 17:30:04

+0

@zzzzBov:對,謝謝。 – 2012-08-10 17:31:28

+0

你的例子都不行。此外,通過輕鬆地錯過+操作將字符串轉換爲整數有點困難,並且使用奇怪的while循環並沒有什麼幫助。 – zatatatata 2012-08-10 17:31:46

0

與其他答案的問題上面的是,在JavaScript中的for..in語言結構將涉及從對象的原型鏈上的所有按鍵。在這種情況下,我們應該檢查並添加正確的密鑰。

var obj= { 
    "125": 2, 
    "439": 3, 
    "560": 1, 
    "999": 2 
} 

var arr=[]; 

for (var item in map) { 
    //important check! 
    if (map.hasOwnProperty(item)) { 
    arr.push(item); 
    } 
} 

另見:http://www.yuiblog.com/blog/2006/09/26/for-in-intrigue/

+0

你有一個觀點,但只有在擴展了Object的原型時纔會發生。這樣做通常令人fr目,而一些知名的庫不支持在這種情況下運行。這是可以理解的,因爲支持它意味着每次迭代一個對象時都會應用您的答案(並且每次迭代花費對hasOwnProperty()的調用)。 – 2012-08-10 17:43:40

+0

以及我假設他的flattening代碼收到一個對象作爲參數,所有的意圖和目的可能來自原型對象。至於衡量「成本」來調用hasOwnProperty與該函數的行爲是否正確,我認爲可以安全地說出哪一個是更安全的選擇。我不喜歡這樣做檢查自己,但這是JavaScript構造如何工作。 – Hyangelo 2012-08-10 17:48:05

0

一個輔助函數:

function flatten(obj){ 
//static Array method: create array (a elements, value b) 
Array.aXb = Array.aXb || function(a,b){ 
    b = b || 0; 
    return String(this(a)).split(',').map(function(){return b;}); 
} 
//obj2array 
var arr = []; 
for (var k in obj) 
    if (+obj[k]) arr = arr.concat(Array.aXb(+obj[k],k)); 
return arr; 
} 
var obj= {"125": 2,"439": 3, 
      "560": 1,"999": 2 }, 
flatten(obj); //=> [125,125,439,439,439,560,999,999]