Reputation: 729
I currently have an array of objects like so:
const array = [
{ key: 'model_1', year: 2019, displayOrder: 1},
{ key: 'model_1', year: 2018, displayOrder: 2},
{ key: 'model_2', year: 2018, displayOrder: 3},
{ key: 'model_3', year: 2018, displayOrder: 4},
{ key: 'model_4', year: 2019, displayOrder: 5},
{ key: 'model_5', year: 2018, displayOrder: 6},
];
I am trying to generate a new array that groups the objects by current
and previous
year and orders by displayOrder
. If we applied this to the above array it would look like this:
const array = {
current: [
{ key: 'model_1', year: 2019, displayOrder: 1 },
{ key: 'model_2', year: 2018, displayOrder: 3 },
{ key: 'model_3', year: 2018, displayOrder: 4 },
{ key: 'model_4', year: 2019, displayOrder: 5 },
{ key: 'model_5', year: 2018, displayOrder: 6 },
],
previous: [
{ key: 'model_1', year: 2018, displayOrder: 2 },
{ key: 'model_4', year: 2018, displayOrder: 7 },
],
};
The theory behind this is that it should show the current version of the model. That will be based on the most recent year for the model.
I have attempted this by creating a reducing function that groups them by year, but I don't think this is the right approach as there could be a lot of overhead than to modify this further.
const modelsByYear = array.reduce((acc, model) => {
acc[model.year] = acc[model.year] || [];
acc[model.year].push(model);
return acc;
}, Object.create(null));
What are some suggestions on how I can do this?
EDIT:
The reason I need this is for filtering. If I click on current
or previous
I need to see the respective models.
Upvotes: 2
Views: 85
Reputation: 386660
You could check the key and splice ither the current array or push to the previous
array.
const array = [{ key: 'model_1', year: 2019, displayOrder: 1 }, { key: 'model_1', year: 2018, displayOrder: 2 }, { key: 'model_2', year: 2018, displayOrder: 3 }, { key: 'model_3', year: 2018, displayOrder: 4 }, { key: 'model_4', year: 2019, displayOrder: 5 }, { key: 'model_5', year: 2018, displayOrder: 6 }, { key: 'model_4', year: 2018, displayOrder: 7 }],
grouped = array.reduce((r, o) => {
var index = r.current.findIndex(({ key }) => o.key === key);
if (index !== -1) {
if (r.current[index].year > o.year) {
r.previous.push(o);
return r;
}
r.previous.push(r.current.splice(index, 1)[0]);
}
r.current.push(o);
return r;
}, { current: [], previous: [] });
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 8239
Considering there is a typo in output, i.e
{ key: 'model_5', year: 2018, displayOrder: 6 }
Should be present in current(as per comment of op). You can try the following:
Sort the array based on key in descending order , year in ascending order and display order in ascending order. After that you can simply iterate over the list and get the desired result. Try the following:
const array = [
{ key: 'model_1', year: 2019, displayOrder: 1},
{ key: 'model_1', year: 2018, displayOrder: 2},
{ key: 'model_2', year: 2018, displayOrder: 3},
{ key: 'model_3', year: 2018, displayOrder: 4},
{ key: 'model_4', year: 2019, displayOrder: 5},
{ key: 'model_5', year: 2018, displayOrder: 6},
];
array.sort((a,b)=> a.key.localeCompare(b.key) || b.year - a.year|| a.displayOrder - b.displayOrder);
var result = {
"current" : [],
"previous" : []
};
for(var i = 0; i < array.length; i++){
if(i == 0 || result.current[result.current.length-1].key != array[i].key){
result.current.push(array[i]);
} else{
result.previous.push(array[i]);
}
}
console.log(result);
Upvotes: 0