Reputation: 575
got a array of objects and need to filter this by 2 criterias. One of those criterias is an index counting up.
let data =
[{"hour": 1, "dayIndex": 0, "value": "something"},
{"hour": 1, "dayIndex": 1, "value": "something"},
{"hour": 1, "dayIndex": 3, "value": "something"},
{"hour": 2, "dayIndex": 0, "value": "something"},
{"hour": 2, "dayIndex": 1, "value": "something"},
// and so on
]
I need an array of objects filtered by "hour" and ascending "dayIndex" and it is important that for missing dayIndexes an empty object is created. So for hour=1 I would need this:
let hourOneArray =
[
{"hour" : 1, "dayIndex": 0, "value": "something"},
{"hour" : 1, "dayIndex": 1, "value": "something"},
{}, //empty because dayIndex 2 is missing
{"hour" : 1, "dayIndex": 3, "value": "something"},
{}, //empty because dayIndex 4 is missing
]
My approach was:
for(let i = 0; i < 4; ++i){
hourOneArray = data.filter((arg) => {
return ((arg.hour === 1) && (arg.dayIndex === i));
})
}
Thanks in advance
Upvotes: 2
Views: 3010
Reputation: 1120
Here's a quick and clean solution to filter all of them by hour, filling in blank days. Make use of map and reduce :D
let data =
[{"hour": 1, "dayIndex": 0, "value": "something"},
{"hour": 1, "dayIndex": 1, "value": "something"},
{"hour": 1, "dayIndex": 3, "value": "something"},
{"hour": 2, "dayIndex": 0, "value": "something"},
{"hour": 2, "dayIndex": 1, "value": "something"},
// and so on
]
let defaultArr = [];
data.forEach(val => defaultArr.push({}));
let output = data.reduce((hash, val) => {
let hour = val.hour;
let dayIndex = val.dayIndex;
if(!hash[hour]) hash[hour] = defaultArr.map(val => val);
hash[hour][dayIndex] = val;
return hash;
}, {})
console.log(output);
Upvotes: 2
Reputation: 28455
You can try following
let data = [{"hour": 1, "dayIndex": 0, "value": "something"},{"hour": 1, "dayIndex": 1, "value": "something"},{"hour": 2, "dayIndex": 0, "value": "something"},{"hour": 2, "dayIndex": 1, "value": "something"},{"hour": 1, "dayIndex": 3, "value": "something"}];
// Sort the array by hour and dayIndex
data.sort((a,b) => a.hour - b.hour || a.dayIndex - b.dayIndex);
function getHourData(hour) {
// Get the hour data
var hourData = data.filter((a) => a.hour === hour);
// Now, iterate till the maximum dayIndex of the filtered array
for (let i = 0; i < hourData[hourData.length -1].dayIndex; i++) {
// If the index is different from dayIndex, count it as missing and add it to the array
if(i !== hourData[i].dayIndex) hourData.splice(i,0, {});
}
// return result
return hourData;
}
console.log(getHourData(1));
Upvotes: 1
Reputation: 370689
You can reduce
into an object indexed by dayIndex
, then add the objects for each missing day, no sorting needed (O(n)
):
const input =
[{"hour": 1, "dayIndex": 0, "value": "something"},
{"hour": 1, "dayIndex": 1, "value": "something"},
{"hour": 1, "dayIndex": 3, "value": "something"},
{"hour": 2, "dayIndex": 0, "value": "something"},
{"hour": 2, "dayIndex": 1, "value": "something"},
];
const [groupedByDay, haveDays] = input
.reduce(([groupedByDay, haveDays], item) => {
const { hour, dayIndex } = item;
if (hour === 1 && !groupedByDay[dayIndex]) {
groupedByDay[dayIndex] = item;
haveDays.push(dayIndex);
}
return [groupedByDay, haveDays];
}, [{}, []]);
const length = Math.max(...haveDays) + 1;
const hourOneArray = Array.from({ length }, (_, i) => (
groupedByDay[i] ? groupedByDay[i] : {}
));
console.log(hourOneArray);
Upvotes: 0
Reputation: 5522
let data =
[{"hour": 1, "dayIndex": 0, "value": "something"},
{"hour": 1, "dayIndex": 1, "value": "something"},
{"hour": 1, "dayIndex": 3, "value": "something"},
{"hour": 2, "dayIndex": 0, "value": "something"},
{"hour": 2, "dayIndex": 1, "value": "something"}]
data= data.sort((a,b)=>a.dayIndex-b.dayIndex);
data = data.map(val=>val.hour == 1?val:{});
console.log(data);
Upvotes: 0