#javascript #arrays #for-loop
#javascript #массивы #for-цикл
Вопрос:
Я хочу сравнить даты из 2 массивов и вставить имя из соответствующей даты в новый массив. А затем нажмите «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 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);
Проблема в том, что он останавливается после обнаружения несоответствующей даты:
Amy,John,0
Это то, что мне нужно
Amy, John, 0, Sara, 0
Ответ №1:
Лучший подход — всегда использовать map
и filter
. Используйте функцию map для fulldate
obj
отфильтровывания объекта (если он присутствует) с той же датой, что и текущее el
значение. Я использовал тернарный оператор в операторе return, который возвращает name, если объект присутствует, и 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);
Комментарии:
1. Спасибо вам за это! Это помогает и намного проще. Я должен больше узнать о map и filter
Ответ №2:
- В вашем коде вы использовали
for-loop
на основеdata
переменной длины, но результат имеет ту же длину,fulldate
поэтому он будет зацикливаться наfulldate
переменной длине. - Внутри цикла вы сравнили
fulldate[i] == data[i].date
, поэтому сравнивали только один и тот же индекс. Внутри цикла вам нужно использовать другой цикл, чтобы найти индекс совпадающей даты.
Вместо использования for
цикла вы можете просто сделать это с помощью Array.prototype.map
функции. (Внутри функции 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);
Комментарии:
1. найденный индекс используется для возврата name .
2. Извините. Пропустил это. В этом случае,
.find
. Вы уже зацикливаетесь, просто получите объект вместо этого.const {name} = data.find(item => item.date === date); return name || '0'
Ответ №3:
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);
Ответ №4:
Предположим, что массивы уже упорядочены по дате, используйте переменную dataIdx
для итерации data
и Array.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] amp;amp; data[dataIdx].date == date ? data[dataIdx ].name : '0');
console.log(newData);
Ответ №5:
для объявления переменной используйте ‘let’ или ‘const’ вместо var. причина: var vs let vs const
И результат, который вы ищете, можно получить с помощью map amp; 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)
к вашему сведению: это также можно сделать с помощью findIndex вместо find .
fulldate.map(date => {
const matchingDateIndex = data.findIndex(nameDateObj => nameDateObj['date'] === date);
return matchingDateIndex > -1 ? data[matchingDateIndex]['name'] : 0;
});
Ответ №6:
Для кратчайшего решения вы должны объединить map и find. Вот 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)