在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 中的每一项,效率不高。
如果您在第一个循环上构建字典并在第二个循环上创建新数组,则可以使用单个 map
和 reduce
来执行此操作。
这也允许lat
和lon
数组的顺序不同。
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中合并两个字典数组的主要内容,如果未能解决你的问题,请参考以下文章