#javascript #arrays #object #if-statement #assign
#javascript #массивы #объект #if-оператор #назначить
Вопрос:
У меня есть два массива объектов:
const testArr1 = [
{
event: "Ryan's birthday",
time: "4:00",
},
{
event: "Steves's birthday",
time: "2:00",
},
{
event: "Helen's birthday",
time: "1:00",
},
{
event: "Paola's birthday",
time: "3:00",
},
{
event: "Jared's birthday",
time: "9:00",
},
];
и
const testArr2 = [
{
time: "4:00",
temp: 41,
},
{
time: "6:00",
temp: 42,
},
{
time: "8:00",
temp: 43,
},
{
time: "1:00",
temp: 44,
},
{
time: "3:00",
temp: 45,
},
{
time: "9:00",
temp: 46,
},
];
Я хотел бы создать функцию, которая принимает эти два массива объектов и возвращает новый массив объектов с именем dataToDisplay
. dataToDisplay
должны содержать объекты, связанные с событиями.
Я хочу, чтобы функция getDataToDisplay
видела, есть ли у события доступные данные о температуре, сравнивая testArr1
и testArr2
значения в time
ключе, а затем предоставила мне массив объектов, которые либо имеют соответствующие temp
данные, когда time
значения совпадают, либо no matching data found
отметили, когда time
значения не совпадают.
Моя проблема заключается в том, что, используя такую функцию, как я его построил теперь, объект продавливают, чтобы dataToDisplay
в каждой итерации возвращает false при сравнении значений времени, так что есть много повторяющихся данных.
Вот функция:
const getDataToDisplay = (testArr1, testArr2) => {
const dataToDisplay = [];
for (let i = 0; i < testArr1.length; i ) {
for (let j = 0; j < testArr2.length; j ) {
let objToPush = {};
//if times in both objects are equal, push an object containing event, time, and temp value at that time to dataToDisplay
//break and move on if times are equal
if (testArr1[i].time === testArr2[j].time) {
Object.assign(objToPush, {
event: testArr1[i].event,
time: testArr1[i].time,
temp: testArr2[j].temp,
});
dataToDisplay.push(objToPush);
break;
} else {
//if times in both objects are NOT equal, push an object containing event, time, and a temp value of "no matching data found"
Object.assign(objToPush, {
event: testArr1[i].event,
time: testArr1[i].time,
temp: "no matching data found",
});
//this is pushing an object every time the condition returns false
//I only want one object returned if false
dataToDisplay.push(objToPush);
}
}
}
return dataToDisplay;
};
вот что происходит при вызове функции
console.log(getDataToDisplay(testArr1, testArr2));
//logs
// [
// {
// "event": "Ryan's birthday",
// "time": "4:00",
// "temperature": 41
// },
// {
// "event": "Steves's birthday",
// "time": "2:00",
// "temperature": "no matching data found"
// },
// {
// "event": "Steves's birthday",
// "time": "2:00",
// "temperature": "no matching data found"
// },
// {
// "event": "Steves's birthday",
// "time": "2:00",
// "temperature": "no matching data found"
// }
// ...
// ]
//but I want it to log something like this
// [
// {
// event: "Ryan's birthday",
// time: "4:00",
// temperature: 41,
// },
// {
// event: "Steves's birthday",
// time: "2:00",
// temperature: "no matching data found",
// },
// {
// event: "Helen's birthday",
// time: "1:00",
// temperature: 44,
// },
// ...
// ];
Как мне просто вернуть один новый измененный объект для каждого события, а не результат каждого из сравнений? Я чувствую, что я так близко!
Ответ №1:
Вы могли бы взять объект для всех времен temparatures
массива и сопоставить events
массив со значениями times
объекта, используя time
в качестве ключа.
const
noData = 'no matching data found',
events = [{ event: "Ryan's birthday", time: "4:00" }, { event: "Steves's birthday", time: "2:00" }, { event: "Helen's birthday", time: "1:00" }, { event: "Paola's birthday", time: "3:00" }, { event: "Jared's birthday", time: "9:00" }],
temperatures = [{ time: "4:00", temp: 41 }, { time: "6:00", temp: 42 }, { time: "8:00", temp: 43 }, { time: "1:00", temp: 44 }, { time: "3:00", temp: 45 }, { time: "9:00", temp: 46 }],
times = Object.fromEntries(temperatures.map(({ time, temp }) => [time, temp])),
result = events.map(o => ({ ...o, temperature: times[o.time] || noData }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ №2:
Вы можете использовать Array.prototype.reduce
и просмотреть каждый объект в testArr1
и найти объект с совпадением temp
в testArr2
с помощью Array.prototype.find
. При совпадении объедините оба, чтобы заполнить «не найдено совпадающих записей»:
const testArr1 = [{ event: "Ryan's birthday", time: "4:00" }, { event: "Steves's birthday", time: "2:00" }, { event: "Helen's birthday", time: "1:00" }, { event: "Paola's birthday", time: "3:00" }, { event: "Jared's birthday", time: "9:00" }],
testArr2 = [{ time: "4:00", temp: 41 }, { time: "6:00", temp: 42 }, { time: "8:00", temp: 43 }, { time: "1:00", temp: 44 }, { time: "3:00", temp: 45 }, { time: "9:00", temp: 46 }];
const getDataToDisplay = (testArr1, testArr2) => {
const defaultText = "no matching records found";
return testArr1.reduce((acc, p) => {
const matchingTime = testArr2.find(t => t.time === p.time);
const temperature = (matchingTime amp;amp; matchingTime.temp) || defaultText;
acc.push({...p, temperature});
return acc;
}, []);
}
console.log(getDataToDisplay(testArr1, testArr2));
Проблема с вашим подходом заключается в том, что вы сравниваете объект из внешнего цикла for с каждым объектом во внутреннем цикле for. Вам нужно только найти объект, который имеет то же время во втором массиве testArr2
если не найден, добавьте сообщение «не найдено совпадающих записей».
Но в вашем случае внутренний цикл помещает новый объект в выходной массив каждый раз, когда происходит несоответствие со time
свойством.