Будьте внимательны при работе с отметками времени, хранящимися в файловой системе FAT32, - они всегда сохраняются в локальных координатах времени (включая DST - см. статью msdn ). Сгорел на этом.
Лично я бы разбил задачу на несколько подзадач (вместо того, чтобы пытаться сделать все это в одной строке), например так:
задача 1: получить все уникальные местоположения
задание 2: для определенного местоположения найдите максимальное количество осадков
задание 3: объедините уникальные местоположения с соответствующими максимальными осадками [ 113]
Если вы напишите функцию для каждого из них, я думаю, вы сможете решить ее самостоятельно.
Вы можете взять карту, собрать максимальное количество осадков в месте и получить новый массив объектов с результатом.
const
weatherArray = [{ Date: "5-1-19", Location: "New York", Rainfall: 4 }, { Date: "5-1-19", Location: "Miami", Rainfall: 8 }, { Date: "5-1-20", Location: "New York", Rainfall: 9 }, { Date: "5-1-20", Location: "Miami", Rainfall: 2 }, { Date: "5-1-21", Location: "New York", Rainfall: 10 }, { Date: "5-1-21", Location: "Chicago", Rainfall: 9 }],
filterData = (inputArray) => {
return Array.from(
inputArray.reduce((m, { Location, Rainfall }) =>
m.set(Location, Math.max(m.get(Location) || 0, Rainfall)), new Map),
([Location, Rainfall]) => ({ Location, Rainfall })
);
};
console.log(filterData(weatherArray));
.as-console-wrapper { max-height: 100% !important; top: 0; }
С датой.
const
weatherArray = [{ Date: "5-1-19", Location: "New York", Rainfall: 4 }, { Date: "5-1-19", Location: "Miami", Rainfall: 8 }, { Date: "5-1-20", Location: "New York", Rainfall: 9 }, { Date: "5-1-20", Location: "Miami", Rainfall: 2 }, { Date: "5-1-21", Location: "New York", Rainfall: 10 }, { Date: "5-1-21", Location: "Chicago", Rainfall: 9 }],
filterData = (inputArray) => {
return Array.from(inputArray
.reduce((m, o) => {
var temp = m.get(o.Location)
return temp && temp.Rainfall > o.Rainfall
? m
: m.set(o.Location, o);
}, new Map)
.values()
);
};
console.log(filterData(weatherArray));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Просто используйте reduce
:
const weatherArray = [{
"Date": '5-1-19',
"Location": 'New York',
"Rainfall": 4
},
{
"Date": '5-1-19',
"Location": 'Miami',
"Rainfall": 8
},
{
"Date": '5-1-20',
"Location": 'New York',
"Rainfall": 9
},
{
"Date": '5-1-20',
"Location": 'Miami',
"Rainfall": 2
},
{
"Date": '5-1-21',
"Location": 'New York',
"Rainfall": 10
},
{
"Date": '5-1-21',
"Location": 'Chicago',
"Rainfall": 9
}
];
const rain = weatherArray.reduce((acc, { Date, Location, Rainfall }) => {
if (acc.some(e => e.Location == Location)) {
if (acc.find(e => e.Location == Location).Rainfall > Rainfall) {
return acc;
}
acc.push({ Date, Location, Rainfall});
acc.splice(acc.findIndex(e => e.Location == Location), 1);
return acc;
}
acc.push({ Date, Location, Rainfall });
return acc;
}, []);
console.log(rain);
.as-console-wrapper { max-height: 100% !important; top: auto; }
Ваша функция далеко не пригодна для использования :) Попробуйте вместо этого просто уменьшить:
weatherArray.reduce((accumulator, current) => {
// check if given city is already in reducing array result
let cityExists = accumulator.findIndex(k => k.Location === current.Location)
if(cityExists > -1) {
// there is a city in resulting array, check values and perhaps update
if(accumulator[cityExists].Rainfall < current.Rainfall) {
accumulator[cityExists].Rainfall = current.Rainfall
accumulator[cityExists].Date = current.Date
}
} else {
// no such city, just add it
accumulator.push(current)
}
return accumulator
}, []) // start with an empty array
Я бы посоветовал вам начать разбивать функциональное программирование на более понятные (для вас) функции, прежде чем пытаться создавать однострочные.
Существует несколько алгоритмов, которые вы можете использовать для своего решения:
На мой взгляд, я считаю, что сначала нужно написать читаемый код, а потом беспокоиться о производительности, если ваши требования к программному обеспечению не требуют производительности в первую очередь.
Поэтому вариант 2 будет моим рекомендуемым решением, и это может быть код:
const rain = {};
weatherArray.forEach(weather => {
const currentCity = weather.Location;
if (rain.hasOwnProperty(currentCity) && rain[currentCity].Rainfall < weather.Rainfall) {
rain[currentCity] = {Rainfall: weather.Rainfall, Date: weather.Date };
} else {
rain[currentCity] = weather;
};)
rain
будет объектом значений:
{
'Miami': {"Date": '5-1-19',
"Rainfall": 8},
'New York': {
"Date": '5-1-21',
"Rainfall": 10},
'Chicago': {
"Date": '5-1-21',
"Rainfall": 9},
}
Может быть легко преобразован в массив, если это ваш окончательный результат. Если доступен ES2016, вы также можете использовать новые итерации Map.