2013-12-09 127 views
4

比方說,我們有以下幾點:獲得唯一對象

node[1].name = "apple"; 
node[1].color = "red"; 
node[2].name = "cherry"; 
node[2].color = "red"; 
node[3].name = "apple"; 
node[3].color = "green"; 
node[4].name = "orange"; 
node[4].color = "orange; 

如果我使用jQuery.unique(節點),我會得到所有的原始節點,因爲他們都有一個不同的名稱或顏色。我想要做的只是得到節點一個獨特的名字,它應該返回

node[1] (apple) 
node[2] (cherry) 
node[4] (orange) 

它不應該返回3,因爲它是相同的水果,即使我們有綠色和紅色的蘋果。

+0

你必須遍歷您的陣列,以創造獨特的相匹配的新陣列。 –

+0

我會改爲使用不同的數據結構,其中'node'是一個對象,並且對象的每個鍵都是水果,每個都包含一個顏色數組。 –

+0

@KevinB也許OP想要一定的順序.... – David

回答

7

使用Array.filter和臨時數組存儲複本:

function filterByName(arr) { 
    var f = [] 
    return arr.filter(function(n) { 
    return f.indexOf(n.name) == -1 && f.push(n.name) 
    }) 
} 

演示:http://jsfiddle.net/mbest/D6aLV/6/

+0

將緩存唯一結果緩存在對象而不是數組中可能會更有效。 – joews

+0

@joews也許,也許不是。但是這可能會破壞訂單,因爲對象是無序的。海事組織,這是更優雅,最有可能有效。 – David

+0

我不明白它爲什麼會影響訂購 - 請參閱我的答案。 – joews

0

什麼做這樣的嗎?

var fruitNames = []; 
$.each($.unique(fruits), function(i, fruit) { 
    if (fruitNames.indexOf(fruit.name) == -1) { 
     fruitNames.push(fruit.name); 
     $('#output').append('<div>' + fruit.name + '</div>'); 
    } 
}); 

Here is a working fiddle

很明顯,而不是output.append我可以將當​​前的水果添加到uniqueFruit []或其他東西。

2

這種方法(來自@David's分支)對大輸入應該有更好的性能(因爲object[]O(1))。

function filter(arr, attribute) { 
    var out = [], 
     seen = {} 

    return arr.filter(function(n) { 
     return (seen[n[attribute]] == undefined) 
       && (seen[n[attribute]] = 1); 
    }) 
} 

console.log(filter(node, 'name')); 

http://jsfiddle.net/LEBBB/1/

+0

我做了一個jsPerf--僅僅因爲我懷疑爲了創建一個微性能點而引發其他答案:http://jsperf.com/uniquearr-obj而且這個方法實際上比較慢。 – David

+0

是的,但正如我所說的,這是針對較大的輸入集(尤其是過濾器屬性的大量唯一值)進行優化的。數組的速度比使用100個不同屬性的500個輸入對象慢很多(〜80%):http://jsperf.com/unique-big-array-object-large – joews

+0

話雖如此,我會用你的答案來輸入較小的數據 - 它更優雅,表現良好。以下是一個jsPerf性能與50個具有10個唯一值的輸入對象類似:http://jsperf.com/unique-big-array-object – joews