简体   繁体   English

比较两个数组并填充缺失值

[英]Comparing two arrays and fill in missing values

I want to compare the dates from 2 arrays and push the name from the matching date inside a new array.我想比较 2 个数组中的日期,并将名称从匹配日期推送到新数组中。 And then push '0' for missing dates.然后为缺少的日期推“0”。

This is what I've tried这是我试过的

 var data = [{ name: 'Amy', date: '2020-01-01' }, { name: 'John', date: '2020-01-02' }, { name: 'Sara', date: '2020-01-04' }]; var fulldate = ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05']; var newData = []; var len = data.length; for (var i = 0; i < len; i++) { if (data[i].date == fulldate[i]) { newData.push(data[i].name); } else if (data[i].date != fulldate[i]) { newData.push("0") } } console.log(newData);

The problem is that it stops after encountering the unmatched date:问题是它在遇到不匹配的日期后停止:

Amy,John,0

This is what I need这就是我需要的

Amy, John, 0, Sara, 0
  • On your code, you have used for-loop based on data variable length but the result has the same length with fulldate so it will be looped based on fulldate variable length.在您的代码中,您使用for-loop基于data可变长度的for-loop ,但结果与fulldate长度相同,因此它将基于fulldate可变长度进行循环。
  • Inside loop, you have compared fulldate[i] == data[i].date so compared only same index.在循环内部,您比较了fulldate[i] == data[i].date所以只比较了相同的索引。 Inside the loop, you need to use another loop to find the index of the matched date.在循环内部,您需要使用另一个循环来查找匹配日期的索引。

Instead of using for loop, you can simply do it using Array.prototype.map function.您可以简单地使用Array.prototype.map函数来代替for循环。 (Inside map function, using Array.prototype.findIndex , you can find the matched date index.) (在 map 函数中,使用Array.prototype.findIndex ,您可以找到匹配的日期索引。)

 var data = [{ name: 'Amy', date: '2020-01-01' }, { name: 'John', date: '2020-01-02' }, { name: 'Sara', date: '2020-01-04' }]; var fulldate = ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05']; const result = fulldate.map((date) => { const existed = data.findIndex(item => item.date === date); return existed >= 0 ? data[existed].name : 0 }); console.log(result);

 var data = [{ name: 'Amy', date: '2020-01-01' }, { name: 'John', date: '2020-01-02' }, { name: 'Sara', date: '2020-01-04' }]; var fulldate = [ '2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05' ]; var newData = []; for(var i = 0; i < fulldate.length; i++) { var found = false; for(var k in data) { if(data[k].date == fulldate[i]) { newData.push(data[k].name); found = true; break; } } if(!found) newData.push("0"); } console.log(newData);

The best approach is always to use map and filter .最好的方法是始终使用mapfilter Use map function on the fulldate The obj filters out the object (if present) with same date, as of current el value.fulldate上使用 map 函数obj过滤掉与当前el值具有相同日期的对象(如果存在)。 I have used ternary operator in the return statement which returns name if object is present, and 0 otherwise.我在 return 语句中使用了三元运算符,如果对象存在则返回名称,否则返回 0。

 var data = [{ name: 'Amy', date: '2020-01-01' }, { name: 'John', date: '2020-01-02' }, { name: 'Sara', date: '2020-01-04' }]; var fulldate = ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05']; var result = fulldate.map((el) => { let obj = data.filter(item => (item.date == el)) return (obj[0]) ? obj[0].name : 0; }) console.log(result);

Suppose the arrays are ordered by date already, use a variable dataIdx to iterate data and Array.map() to simplify the for loop.假设数组已经按日期排序,使用变量dataIdx来迭代dataArray.map()来简化 for 循环。

 var data = [{name:'Amy', date:'2020-01-01'}, {name:'John', date:'2020-01-02'}, {name:'Sara', date:'2020-01-04'}]; var fulldate = ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05']; var dataIdx = 0; var newData = fulldate.map(date => data[dataIdx] && data[dataIdx].date == date ? data[dataIdx++].name : '0'); console.log(newData);

for variable declaration, use 'let' or 'const' instead of var.对于变量声明,使用 'let' 或 'const' 而不是 var。 reason: var vs let vs const原因: var vs let vs const

And, the result you are looking for can be done using map & find js func.而且,您正在寻找的结果可以使用 map & find js func 来完成。

 const fulldate = ["2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05"]; const data = [ {name: "Amy", date: "2020-01-01"}, {name: "John", date: "2020-01-02"}, {name: "Sara", date: "2020-01-04"} ]; const result = fulldate.map(date => { const matchingDate = data.find(nameDateObj => nameDateObj['date'] === date); return matchingDate ? matchingDate['name'] : 0; }); console.log(result)

fyi: this can also be done using findIndex instead of find too.仅供参考:这也可以使用 findIndex 而不是 find 来完成。

fulldate.map(date => {
     const matchingDateIndex = data.findIndex(nameDateObj => nameDateObj['date'] === date);
     return matchingDateIndex > -1 ? data[matchingDateIndex]['name'] : 0; 
});

For shortest solution you should combine map and find.对于最短的解决方案,您应该结合 map 和 find。 Here is a oneliner:这是一个单线:

 const data = [{ name: 'Amy', date: '2020-01-01' }, { name: 'John', date: '2020-01-02' }, { name: 'Sara', date: '2020-01-04' }]; const fulldate = ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05']; const result = fulldate.map(x => (data.find(y => y.date === x) || {name: 0}).name) console.log(result)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM