2017-08-30 71 views
3

第一陣列有效地合併日期對象的兩個陣列是含有獨特的javascript日期對象日期的對象的主列表:如何使用lodash

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

第一陣列是包含日期的對象的更小的列表獨特的JavaScript Date對象的子集,與「價值」屬性始終具有許多而不是一個null

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

銘記比較日期對象的細微差別 - https://stackoverflow.com/a/493018/538962 - 這將是最efficie nt合併這些對象的方式 - 在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... 
] 
+0

是否每個列表已經排序? – TimCodes

+0

有沒有重複?對同一個Date對象的多次引用,或者具有相同時間值的唯一日期? – RobG

+0

@TimCodes - yes;每個列表已經排序。 – mg1075

回答

1

您可以使用內置的Array.prototype.map從現有的數組值中創建一個新的數組。

如果你說:

第一個數組是包含獨特的javascript日期的一個子集Date對象的一個​​更小的對象列表

我假設dateobject3是兩個數組中的相同對象,而不是同一日期的兩個不同對象。

下面創建用於值的索引數組來保存迭代過數據的每個成員。對於小數據集(比如小於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)

如果每一日期,只會有一個比賽,你可以通過在匹配時刪除匹配的索引來進一步優化,以便後續查找(可能不知不覺)更快。

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; 
}, []); 
+1

這使得* masterList *的成員在'Object.assign(b,match)'處發生變異,因此完成時* mergedArray *是對變異* masterList *中元素的引用的集合。所以你可以使用* forEach *而不是* reduce *,而不用擔心* mergedArray *。 ;-) – RobG

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 
}) 
+0

使用時間值作爲密鑰提出了重複日期的問題。此外,您正在構建一個普通對象,而不是散列。區別可能很微妙,但ECMAScript可能在將來獲得真正的哈希(例如,它最近獲取了Map和Set對象)。您可以創建一個Map並使用Date對象本身作爲鍵(如果兩個數組中的日期是相同的對象)。不知道,如果這就是OP所指的「* ...包含獨特的javascript Date對象*的一個子集」。 – RobG