2012-05-07 17 views
4

有一個具有這種結構的數據:Javascript:如何將對象數組轉換爲具有排序的唯一數組的對象?

$input = [ { animal: 'cat', name: 'Rocky', value: 1 }, 
      { animal: 'cat', name: 'Spot', value: 2 }, 
      { animal: 'dog', name: 'Spot', value: 3 } ]; 

需要儘可能最快的方法,用於轉換爲如下格式:

$output = { animal: [ 'cat', 'dog' ], 
      name: [ 'Rocky', 'Spot' ], 
      value: [ 1, 2, 3 ] }; 

輸出應具有等於每個鍵的鍵在從每個對象輸入。輸出值應該是具有排序的唯一值的數組。我發現了幾種使用嵌套循環的方法,但比我想要的要慢。在輸入數組中有30,000個元素,每個對象有8個鍵,我能夠做的最好的事情是Chrome中的300ms。想下降到100ms。有沒有更快的方法使用地圖或縮小?

+5

爲什麼不發表你目前有什麼?看起來像將數值推入數組一樣簡單,然後在最後刪除/排序。 – Tejs

+0

它始終是時空權衡和效率。你可以交易空間的時間。 –

+0

請記住,$不是JavaScript--這是一個PHP變量。嵌套循環是最好的你會得到的 - 這是你所有的。你爲什麼要改變這種結構?投入看起來似乎更加合理和可用。 – Bradley

回答

2

這裏有一種方法。

$input = [ { animal: 'cat', name: 'Rocky', value: 1 }, 
      { animal: 'cat', name: 'Spot', value: 2 }, 
      { animal: 'dog', name: 'Spot', value: 3 } ]; 

$output = {animal:{},name:{},value:{}}; 

$input.forEach(function(v,i) { 
    $output.animal[v.animal] = 1; 
    $output.name[v.name] = 1; 
    $output.value[v.value] = 1; 
}); 

$output.animal = Object.keys($output.animal); 
$output.name = Object.keys($output.name); 
$output.value = Object.keys($output.value); 

它可以防止每次都測試每個陣列。你可以比較性能,看看它是否有幫助。

活生生的例子:http://jsfiddle.net/TJVtj/1/


如果你不想硬編碼鍵,可以使溶液一般。

var keys = Object.keys($input[0]), 
    $output = {}; 

keys.forEach(function(v) { 
    $output[v] = {}; 
}); 

$input.forEach(function(v) { 
    keys.forEach(function(vv) { 
     $output[vv][v[vv]] = 1; 
    }); 
}); 

keys.forEach(function(v) { 
    $output[v] = Object.keys($output[v]); 
}); 

活生生的例子:http://jsfiddle.net/TJVtj/2/

警告。所有值都是字符串,因爲它們被作爲對象鍵提取。

0
function inArray(needle, haystack) { 
    var length = haystack.length; 
    for(var i = 0; i < length; i++) { 
     if(haystack[i] == needle) return true; 
    } 
    return false; 
} 

以上函數是用來檢查重複

$output={}; 
for(i=0; i< $input.length; i++) 
{ 
    if(!$output.animal) $output.animal=[]; 
    if(!$output.name) $output.name=[]; 
    if(!$output.value) $output.value=[]; 
    var ani=$input[i]; 
    if(ani.animal && !inArray(ani.animal, $output.animal)) $output.animal.push(ani.animal); 
    if(ani.name && !inArray(ani.name, $output.name)) $output.name.push(ani.name); 
    if(ani.value) $output.value.push(ani.value); 
} 

DEMO.

0

//如果你不知道的對象都需要看每個單相同的密鑰

var output= {}, 
input= [{ 
    animal:'cat', name:'Rocky', value:1 
},{ 
    animal:'cat', name:'Spot', value:2 
},{ 
    animal:'dog', name:'Spot', value:3 
}]; 
input.forEach(function(itm){ 
    for(var p in itm){ 
     if(itm.hasOwnProperty(p)){ 
      if(!output[p]) output[p]= []; 
      if(output[p].indexOf(itm[p])== -1) output[p].push(itm[p]); 
     } 
    } 
}); 

Run.expose(output)// nonstandard object to string method 

// returned value: (String) 
{ 
    animal:[ 
     'cat', 
     'dog' 
    ], 
    name:[ 
     'Rocky', 
     'Spot' 
    ], 
    value:[ 
     1, 
     2, 
     3 
    ] 
} 
2

現代瀏覽器的又一種方式:

$input.reduce(function(acc, obj) { 
    Object.keys(obj).forEach(function(k) { 
    acc[k] = (acc[k] || []).concat(obj[k]) 
    }) 
    return acc 
},{}) 
+0

這是實現它的功能「下劃線」方式!這應該是最好的答案! –

相關問題