如何使用lodash

时间:2017-08-30 00:01:29

标签: javascript arrays json date lodash

第一个数组是包含唯一javascript Date对象的日期对象的主列表:

[
   {'date': dateobject1, 'value': null},
   {'date': dateobject2, 'value': null},
   {'date': dateobject3, 'value': null},
   etc...
]

第一个数组是一个小得多的日期对象列表,其中包含唯一的javascript Date对象的子集,其中'value'属性始终具有数字而不是null

[
   {'date': dateobject3, 'value': 3117},
   {'date': dateobject8, 'value': 14},
   etc...
]

记住比较日期对象的细微差别 - https://stackoverflow.com/a/493018/538962 - 合并这些对象的最有效方法 - 在lodash 3.10.1可用的环境中 -  基于匹配日期,以便合并的数组是所有日期的列表:匹配意味着'值'成为数值,否则当没有匹配时保留null'值'?

[
   {'date': dateobject1, 'value': null},
   {'date': dateobject2, 'value': null},
   {'date': dateobject3, 'value': 3117},
   {'date': dateobject4, 'value': null},
   {'date': dateobject5, 'value': null},
   {'date': dateobject6, 'value': null},
   {'date': dateobject7, 'value': null},
   {'date': dateobject8, 'value': 14},
   etc...
]

3 个答案:

答案 0 :(得分:2)

您可以使用内置的 Array.prototype.map 从现有数组值创建新数组。

你说的地方:

  

第一个数组是一个小得多的日期对象列表,其中包含唯一的javascript Date对象的子集

我假设 dateobject3 是两个数组中的同一个对象,而不是同一日期的两个不同对象。

以下内容为 values 数组创建一个索引,以便为 data 的每个成员保存迭代。对于小数据集(比如少于100个值),它不会产生明显的差异,但对于较大的数据集(例如超过几百或一千),它将不会产生明显的差异。

var d0 = new Date(2017,1,1),
    d1 = new Date(2017,1,2),
    d2 = new Date(2017,1,3);

var data = [
   {'date': d0, 'value': null},
   {'date': d1, 'value': null},
   {'date': d2, 'value': null}
];

var values = [
   {'date': d1, 'value': 3117},
];

// Generate a values index, saves searching
// through values for each member of data
var indexes = values.map(obj => obj.date);
// Generate merged array
var merged = data.map(obj => {
  var index = indexes.indexOf(obj.date); 
  return {date: obj.date, value: index > -1? values[index].value : obj.value};
});

console.log(merged)

另一方面,如果日期是不同的对象但具有相同的时间值,则需要比较时间值。获取时间值的一种简单方法是使用一元+,它只是在 getValue getTime 上保存输入:

var data = [
   {'date': new Date(2017,1,1), 'value': null},
   {'date': new Date(2017,1,2), 'value': null},
   {'date': new Date(2017,1,3), 'value': null}
];

var values = [
   {'date': new Date(2017,1,2), 'value': 3117},
];

// Generate a values index using the date time value
// saves searching through values for each member of data
var indexes = values.map(obj => +obj.date);
// Generate merged array
var merged = data.map(obj => {
  var index = indexes.indexOf(+obj.date); 
  return {date: obj.date, value: index > -1? values[index].value : obj.value};
});

console.log(merged)

如果每个日期只有一个匹配项,您可以通过在匹配的索引匹配时删除它们来进一步优化,以便后续查找(可能在不知不觉中)更快。

答案 1 :(得分:0)

好问题。我将在主列表上使用reduce方法来查看其他列表是否包含匹配日期 - 如果这样合并两个对象并推送到新数组,如果不是仅从主列表中推送对象。请注意,这是使用es6 - 如果在您使用的环境中无法使用es6,则lodash具有reduceassign方法

const masterList = [/* ... */];
const otherArray = [/* ... */];

const mergedArray = masterList.reduce((a, b) => {
  const match = otherArray.filter(({ date }) => date.getTime() === b.date.getTime());
  if(match) {
    a.push(Object.assign(b, match));
  } else {
    a.push(b);
  }

  return a;
}, []);

答案 2 :(得分:0)

使用hashset思考将是更快捷的方法之一 https://codepen.io/TimCodes/pen/brQvbo?editors=0012

var masterListArr = [ { 'date' : new Date(), 'value' : 2 } , {'date' : new Date(2013, 13, 1), 'value' : 0}]
var secondListArr = [ { 'date' : new Date(), 'value' : null } , {'date' : new Date(2014, 13, 1), 'value' : null}]

var masterListHash = masterListArr.reduce(function(acc, cur, i) {
  acc[cur['date'].getTime()] = cur['value'] ;
  return acc;
}, {});


var mergedList = secondListArr.map(dateObj => {
   var dateKey = dateObj.date.getTime()
   if(masterListHash.hasOwnProperty(dateKey)){
        dateObj.value = masterListHash[dateKey]
   }
   return dateObj
})