Basically, I am given a data set just like the one I provided below and all follow the same pattern and have the same amount of keys and values. However, I am looking to group them in a way where the "make" stays the same, and if the array has more objects with the same "make" the "model" values are pushed into an array as shown in the example 2.
const cars = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}
];
And here is the end result that I am looking for:
const carByMake = [
{
'make': 'audi',
'models': ['r8', 'rs5']
'years': ['2012, 2013']
},
];
CodePudding user response:
you can do like this
const cars = [
{
make: "audi",
model: "r8",
year: "2012",
},
{
make: "audi",
model: "rs5",
year: "2013",
},
{
make: "audi",
model: "rs6",
year: "2013",
},
{
make: "bmw",
model: "x5",
year: "2013",
},
{
make: "bmw",
model: "x6",
year: "2013",
},
];
let tempArr = [];
let unique = cars.map((data) => {
let filterDataArr = tempArr.filter(
(filterData) => filterData.make == data.make
);
if (filterDataArr && filterDataArr.length > 0) {
filterDataArr[0].models = [...filterDataArr[0].models, data.model];
filterDataArr[0].years = [...filterDataArr[0].years, data.year];
} else {
let dataArr = {
make: data.make,
models: [data.model],
years: [data.year],
};
tempArr.push(dataArr);
}
});
console.log("tempArr=>", tempArr);
CodePudding user response:
There is a way more fundamental way to do what your asking.
This is a very basic problem, and should be solved using a basic solution. There isn't a need to filter the results, as a simple loop with an if statement can produce the results that your asking for. Fundamentally, the solution for this problem is technically a sort-algorithm, just a very simple one.
You could use a "for of" loop, but I feel like this is a prime example where a forEach loop shows how powerful it is. ForEach is abstracted a level above your low-level while
& for
loops. That extra layer of abstraction allows a function to be passed into the forEach loop. Each time (hence the name "each") the forEach
loop iterates, the forEach's callback is executed, until the array that the forEach loop was called on has been fully iterated through (there are exceptions, but I don't want to get off track).
You can use the forEach loop to solve your problem. That solution is demonstrated below. I documented the code w/ JSDoc so you can copy & paste it into your editor, and have the parameters & types shown in your tool-tip/hover-widget.
const cars = [
{ make: 'audi', model: 'r8', year: 2012 },
{ make: 'audi', model: 'rs5', year: 2013 },
];
/**
* @param {string} make - The make that you want to return the models &
years for
* @param {{make: string, model: string, year: number}[]} cars - An
array of car objects that include the model make & year
* @return {{make: string, models: string[], years: string[]}}
* */
function sortByMake(make, cars) {
const models = [];
const years = [];
cars.forEach((car) => {
if (car.make.toLowerCase() === make.toLowerCase()) {
models.push(car.model);
years.push(car.year);
}
});
return { make: make, models: models, years: years };
}
console.log(sortByMake('Audi', cars));
// OUTPUT:
// $ node ./index.js
// {make: 'Audi', models: ['r8', 'rs5'], years: [2012, 2013]}