2013-12-09 33 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