是否有非循环每单列表项查找唯一列表项?

时间:2014-07-21 23:37:49

标签: javascript

我知道我可以使用loop-every-single-list-item方法来过滤掉给定列表中的唯一元素,但我觉得这可能是一个简洁,快捷的方法。

如何在JavaScript中找到唯一列表项,而无需手动循环并过滤它们?

最近我正在处理事件处理补丁,需要快速方法来过滤掉回调列表中的独特函数处理程序,这些函数必须经常运行。

这是我想要做的事情:

  Array.prototype.unique = (function () {

    // main Array#unique method
    var uni = function uni () {
      return this.filter(uni.x);
    };

    // attach a helper for resolving unique elements
    // if element is at current position, not before, 
    // it's unique one, pass `true` flag to .filter()
    uni.x = function (node, pos, ls) {
      return pos === ls.indexOf(node);
    };

    // save
    return uniq;
  })();

实现:

// sample list:
//   generate ~1K long list of integers:
//     get the keys of string object of length 32,
//     map every item to key-list itself, 
//     flatten, shuffle..
var ls = 
  Array.prototype.concat.apply([], 
    Object.keys(new String('1'.repeat(32)))).
  map(function (node, pos, list) { return list; }).
  sort(function () { return Math.random() < Math.random(); });

// run each function 1K times fetching unique values 
for (

  var 
    it   = -1, 
    l    = 1000, 

    // record iteration start
    tm   = Date.now();

  ++it < l; 

  ls.unique()

);

3 个答案:

答案 0 :(得分:1)

没有。如果您有一个列表,则需要在每个项目上至少查看一次以确定它是否是唯一的。

如果您需要更快的东西,请不要使用列表。

顺便说一句,即使在列表中,您也可以在低于当前unique的情况下实施O(n²) - 算法。有关一些聪明的方法,请参阅Easiest way to find duplicate values in a JavaScript array

  

我正在研究事件处理补丁,并且需要快速方法来过滤回调列表中的独特函数处理程序,这些函数处理程序必须经常运行。

然后你不想把它们放在那个列表中。运行时不要检查列表中的重复项(正如您所说的那样),但是当您插入新的处理程序时。

如果您认为使用.indexOf在列表中查找处理程序仍然太慢,则可以将每个函数对象标记为已包含在列表中。选择唯一(每个列表)属性名称,并在列表中的每个函数的属性上添加一个值。然后,您可以在常量运行时检查重复项。

答案 1 :(得分:0)

如果您有一个唯一的密钥,使用字典是一个不错的选择。但是,如果你有一些逻辑需要执行来执行过滤,我会选择UnderscoreJS。查看_.filter方法。这是一个很棒的图书馆,在这个地区提供很多。

http://underscorejs.org/#filter

答案 2 :(得分:0)

我不认为有一种方法可以在不迭代每个项目的情况下获得唯一的项目列表。如果你正在寻找一个内置的库函数,我不认为Angular中有一个。

创建一个很简单:

function unique(array, fn) { 
   var hash = [];
   var list = [];
   for(var i = 0; i < array.length; ++i) {
        var key = fn(array[i]);
        if (key && !hash[key]) {
           list.push(array[i]);
           hash[key] = key;
        }
   }
   return list;
}

用法:

var myList = [ { id:1, name="oranges"},
               { id:2, name="apples" },
               { id:1, name="oranges"},
               { id:3, name="pears" },
               { id:3, name="pears" } ];

var uniqueList = unique(myList, function(item) { return item.id; });