在javascript中合并两个字典数组

Posted

技术标签:

【中文标题】在javascript中合并两个字典数组【英文标题】:Merge two arrays of dictionaries in javascript 【发布时间】:2018-04-22 18:34:01 【问题描述】:

我有两个字典数组,看起来像这样:

var lat = [key:"2017-09-20T11:51:32.000Z", value:50.7825333,key:"2017-09-20T11:51:33.000Z", value:50.7826,...];
var lon = [key:"2017-09-20T11:51:32.000Z", value:-1.3075833,key:"2017-09-20T11:51:33.000Z", value:-1.3076,...];

您可能已经猜到一个是纬度数组和经度数组!

我想要一种优雅的方式将时间、纬度、经度合并到一个数组中。两个数组都包含相同的键(我应该检查一下是否总是这样!)。

var latLon = [time:"2017-09-20T11:51:32.000Z", lat:50.7825333, lon:-1.3075833,...]

我已经将一些可行但不漂亮的东西放在一起(即迭代两个数组并附加到一个新数组),但感觉必须有一种更时尚的方式来使用 Object.assign 和一些不错的 lamdas。如果包含任何有用的方法,我也会使用 D3.js 库。

【问题讨论】:

最好将您尝试过的代码添加到您的问题中。 我在工作,没有太多时间来确保这是正确的,但您可以查看 lodash 和/或下划线的 zip 方法 -- lodash.com/docs/4.17.4#zip 【参考方案1】:

您可以使用Array#map 方法生成新数组(假设两个数组的顺序相同)。

var lat = [key:"2017-09-20T11:51:32.000Z", value:50.7825333,key:"2017-09-20T11:51:33.000Z", value:50.7826];
var lon = [key:"2017-09-20T11:51:32.000Z", value:-1.3075833,key:"2017-09-20T11:51:33.000Z", value:-1.3076];


var res = lat
  // iterate over the first array
  .map(function(o, i) 
    // generate the array element
    // where get values from element and
    // get value from second array using
    // the index
    return 
      time: o.key,
      lat: o.value,
      lon: lon[i].value
    
  )

console.log(res);

// with ES6 arrow function
var res1 = lat.map((o, i) => (time: o.key, lat: o.value, lon: lon[i].value))


console.log(res1);

仅供参考: 如果相关数组元素的顺序不同,则需要通过比较时间值从第二个数组中获取元素(您可以使用Array#find 方法)或者您可以生成映射对象的 hashmap。

Array#find方法:

var lat = [key:"2017-09-20T11:51:32.000Z", value:50.7825333,key:"2017-09-20T11:51:33.000Z", value:50.7826];
var lon = [key:"2017-09-20T11:51:32.000Z", value:-1.3075833,key:"2017-09-20T11:51:33.000Z", value:-1.3076];



var res = lat
  .map(function(o) 
    return 
      time: o.key,
      lat: o.value,
      // get object by using find method
      lon: lon.find(function(o1) 
        return o1.key === o.key;
      ).value
    
  )

console.log(res);

// with ES6 arrow function
var res1 = lat.map(o => (
  time: o.key,
  lat: o.value,
  lon: lon.find(o1 => o1.key === o.key).value
))

console.log(res1);

使用哈希图进行引用的更有效方法:

var lat = [key:"2017-09-20T11:51:32.000Z", value:50.7825333,key:"2017-09-20T11:51:33.000Z", value:50.7826];
var lon = [key:"2017-09-20T11:51:32.000Z", value:-1.3075833,key:"2017-09-20T11:51:33.000Z", value:-1.3076];

// generate reference hashmap for getting 
// value using the datetime string
var ref = lon.reduce(function(obj, o) 
  // set reference
  obj[o.key] = o.value;
  // return the reference object
  return obj;
  // set initial value as an empty object
, );

var res = lat
  .map(function(o) 
    return 
      time: o.key,
      lat: o.value,
      // get value from generated reference object
      lon: ref[o.key]
    
  )

console.log(res);

【讨论】:

【参考方案2】:

我会避免使用find(),如果有任何机会你会处理很多物品。 find() 需要在第二个数组中搜索 lat 中的每一项,效率不高。

如果您在第一个循环上构建字典并在第二个循环上创建新数组,则可以使用单个 mapreduce 来执行此操作。

这也允许latlon 数组的顺序不同。

var lat = [key:"2017-09-20T11:51:32.000Z", value:50.7825333,key:"2017-09-20T11:51:33.000Z", value:50.7826];
var lon = [key:"2017-09-20T11:51:32.000Z", value:-1.3075833,key:"2017-09-20T11:51:33.000Z", value:-1.3076];

var obj = lat.reduce((a, c) => (a[c.key] = time: c.key, lat:c.value, a), );
var arr = lon.map(lon => Object.assign(obj[lon.key], lon: lon.value));

console.log(arr);

【讨论】:

如果你有机会处理很多项目,我会避免使用 find()。实际上使用find,您将循环直到找到请求的对象,而使用您的实际代码,您将循环整个数组两次,一次使用reduce(),下一次使用.map(),所以我认为使用find() 会更高效。 ;) @chsdk 你的答案中的find()map() 内,这意味着find() 会为lat 中的每个项目调用。如果有 100 个项目,则调用 find() 100 次。这比 2 个循环差得多。 是的,我同意你的看法,如果有很多项目(BTW 100 不是那么大),但find() 会尽快找到object,无论如何理论上它更糟,但它们的实施是为了保证性能。但是如果对象在两个数组中的排序方式相同,那么所有这些问题都将被真正忽略。但无论如何不要从你提供的伟大解决方案中获取任何东西。 :) 你正在使用 ES6 箭头函数,浏览器对这些函数的支持如何? @Taurus caniuse.com/#feat=arrow-functions 看起来全球不到 80%。【参考方案3】:

这是基于key 时间。假设没有相同的键/时间,那么您可以这样做:

var lat = [key:"2017-09-20T11:51:32.000Z", value:50.7825333,key:"2017-09-20T11:51:33.000Z", value:50.7826];
var lon = [key:"2017-09-20T11:51:32.000Z", value:-1.3075833,key:"2017-09-20T11:51:33.000Z", value:-1.3076];

var obj = , arr = lat.concat(lon);

arr.forEach(function(x)
    obj[x.key] ? obj[x.key]["lon"] = x.value : obj[x.key] = lat: x.value, time: x.key;
);

var latlon = Object.keys(obj).map(function(x)
    return obj[x];
);

您正在连接 2 个数组以组成一个数组。然后,您将使用时间作为键创建字典(这是假设您没有两个 lats 和两个 longs 具有相同时间的地方)。既然您知道您首先获得的是 lats,那么您的下一个关键比赛应该是 lons。

【讨论】:

以上是关于在javascript中合并两个字典数组的主要内容,如果未能解决你的问题,请参考以下文章

javascript合并两个数组

将两个 json/javascript 数组合并为一个数组

javascript合并两个json对象

如何根据javascript中的键合并和替换两个数组中的对象?

javascript 两个 数组 怎么 合并 显示

java中怎么合并两个数组 简单明了的