如何通过唯一键/值获取前n个对象

时间:2015-09-27 16:49:14

标签: javascript underscore.js lodash

我有一个包含数百个对象的数组,其中包含地理位置数据,如下所示:

var geoArray = [
  {
    name: "a",
    latitude: 34.0500,
    longitude: 118.2500
    ...
  },
  {
    name: "b",
    latitude: 40.7127,
    longitude: 74.0059,
    ...
  },
  ...
];

我想获取每个唯一纬度/经度对的前10个对象,并将这些对象集合放入新数组中。什么是有效的方法来实现这一目标?我愿意使用lodash或下划线。

使用下划线uniq我可以执行以下操作,但这只会让我得到第一个基于lat / lng而不是前10个的对象:

_.uniq(geoArray,function(element) { return element.latitude + "_" + element.longitude});

这是_uniq的实际定义:

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

我想要的功能基本上是这样的: _.uniq(array, [isSorted], [iteratee], [limit])默认情况下limit为1,但我想输入10.我知道我可以先抓住唯一的lat / lng对,然后找到哪些对象都有它们并将它们推送到数组最多10次,等等。但我希望有一种更有效的方法。

以下是应用以下非常有用的答案后可以使用的确切代码:

function getUnique(arr, limit) {
  var indices = [];
  var out = [];
  for (var i = 0, l = arr.length; i < l; i++) {
     var location = arr[i].latitude + '_' + arr[i].longitude;
     if (indices.indexOf(location) === -1) {
       out.push(arr.filter(function (el) {
         return el.latitude + '_' + el.longitude === location
       }).slice(0, limit));
       indices.push(location);
     }
  }
  return out;
}

2 个答案:

答案 0 :(得分:1)

现在我想我明白你的问题是什么,this is the most efficient method我能想到的。它返回一组具有相同id的对象组。你必须根据你的数据进行调整*,但这是要点。

function getUnique(arr, limit) {
    var indices = [];
    var out = [];
    for (var i = 0, l = arr.length; i < l; i++) {
       var id = arr[i].id;
       if (indices.indexOf(id) === -1) {
         out.push(arr.filter(function (el) {
             return el.id === id;
         }).slice(0, limit));
         indices.push(id);
       }
    }
    return out;
}

getUnique(arr, 3);

DEMO

  • 我使用了一个简单的数组,因为我不想在这个例子中使用lat / lon coords创建大量对象。

答案 1 :(得分:0)

使用lodash group by:

var grouped = _.groupBy(geoArray, function(item){return item.lat + ',' + item.long; };
var valuesByLocation = _.values(grouped);
var valuesByLocation_First10 = _.map(valuesByLocation, function(value){ return _.take(value, 10); });

显然,你可以使用_.partial或链接将所有内容组合成一个内衬。