使用underscore.js基于双重属性查找唯一值

时间:2014-09-30 23:10:41

标签: javascript underscore.js

使用Underscore.js,我试图在一个如下所示的数组中获取唯一值:

var links = [
    {source: 0, target: 1},
    {source: 0, target: 2},
    {source: 0, target: 3},
    {source: 0, target: 4},
    {source: 0, target: 1},
    {source: 4, target: 0}
];

所以它最终会像这样结束:

var links = [
    {source: 0, target: 1},
    {source: 0, target: 2},
    {source: 0, target: 3},
    {source: 0, target: 4},
];

我想摆脱具有相同来源和链接的链接当然,目标对的顺序相同(0,1 == 0,1),但也想摆脱那些相同但倒置的(0,4 == 4,0)。

我确信我可以使用双嵌套的_.map()来做这件事,但是想看看那里的任何Underscore魔术师是否有更清洁,更合适的解决方案。

2 个答案:

答案 0 :(得分:4)

我认为_.uniq就是答案。

uniq_.uniq(array, [isSorted], [iteratee])

More info

我相信您可以使用第三个参数(iteratee)来提供在比较之前首先应用的自定义变换函数。

使用_.uniq(http://jsfiddle.net/muto6zs1/)的示例:

function(item) {
  // sort array of source and target and join it into a delimited string for a unique value
  return [item.source, item.target].sort().join(',');
}

答案 1 :(得分:1)

您已经使用下划线得到了答案,但为了帮助您了解幕后发生的事情,我提供了一个JavaScript示例:

var links = [
    {source: 0, target: 1},
    {source: 0, target: 2},
    {source: 0, target: 3},
    {source: 0, target: 4},
    {source: 0, target: 1},
    {source: 4, target: 0}
];

// create a temporary buffer to hold unique keys
var keys = {};
links.forEach(function(item, index) {
  // this is the essential part of the uniqueness test
  var item = [item.source, item.target].sort();

  if (!keys.hasOwnProperty(item)) {
      keys[item] = index;
  }
});

// iterate over the unique keys and reconstruct a new array
links = Object.keys(keys).reduce(function(prev, index) {
  prev.push(links[keys[index]]);
  return prev;
}, []);

console.log(links);