I have an array of objects (cars), from which I want to show just the cars which "compete".
const cars = [
{
name: "red",
competes: true,
category: 1
},
{
name: "blue",
competes: false,
category: 1
},
{
name: "green",
competes: true,
category: 2
},
{
name: "yellow",
competes: true,
category: 3
}
]
But from those cars which compete, i only want to show those cars which are in category one, which is fine with a for loop.
The objects are now static but since i want to change them in a second moment, i need a code which checks if the cars compete and then checks if there are cars in "category" one.
- If there are cars in "category 1", list them
- If there are no cars in "category" 1, list those in "category" 2 (but not 3)
- And so on
My try was with a loop inside a loop, bit that doesnt work since it displays all multiple times
for (let i = 0; i < cars.length; i ) {
if (cars[i].competes === false) continue;
for (let f = 0; f < cars.length; f ) {
if (cars[f].category > 1) break;
console.log(`Cat1: ${cars[f].name}`);
}
}
How can this be resolved if the "category" attributes inside "cars" are for example all 2 or more?
const cars = [
{
name: "red",
competes: true,
category: 2
},
{
name: "blue",
competes: false,
category: 2
},
{
name: "green",
competes: true,
category: 3
},
{
name: "yellow",
competes: true,
category: 4
}
]
CodePudding user response:
First of all you sort the array based on the category and then filter out an array with cars that are gonna compete
const cars = [
{
name: "red",
competes: true,
category: 1
},
{
name: "blue",
competes: false,
category: 1
},
{
name: "green",
competes: true,
category: 2
},
{
name: "yellow",
competes: true,
category: 3
}
]
const sorted = cars.sort((a, b) => a.category - b.category);
const compete = sorted.filter(x => x.competes && x.category == sorted[0].category);
console.log(compete[0]);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Here is a simple solution with sort and filter
const cars = [
{
name: "red",
competes: true,
category: 1
},
{
name: "blue",
competes: false,
category: 1
},
{
name: "green",
competes: true,
category: 2
},
{
name: "yellow",
competes: true,
category: 3
}
]
let result = cars.sort((a,b) => a.category - b.category)
.filter(car => car.competes && (cars.length && car.category == cars[0].category))
console.log(result)
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
We can start by getting the 'competing category' by getting the lowest competing category present, using Math.min()
and Array.filter()
We can then get all competing cars by using Array.filter()
to return only cars with a competes
value that is truthy and also belongs to the competing category.
const cars = [ { name: "red", competes: true, category: 1 }, { name: "blue", competes: false, category: 1 }, { name: "green", competes: true, category: 2 }, { name: "yellow", competes: true, category: 3 } ]
// Only this category is competing..
const competingCategory = Math.min(...cars.filter(car => car.competes).map(({category}) => category));
const competingCars = cars.filter(car => car.competes && car.category === competingCategory);
console.log('Competing cars:', competingCars)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
This example has only category 2 and 3 present:
const cars = [ { name: "blue", competes: true, category: 2 }, { name: "green", competes: true, category: 2 }, { name: "yellow", competes: true, category: 3 } ]
// Only this category is competing..
const competingCategory = Math.min(...cars.filter(car => car.competes).map(({category}) => category));
const competingCars = cars.filter(car => car.competes && car.category === competingCategory);
console.log('Competing cars (example II):', competingCars)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>