Search code examples
javascriptarrayssortingarrayobjectcompareobject

filter and sum data from 2 array of objects to a new array in JS


I have 2 arrays of JavaScript objects:

const typeCrop = [
    { id: 1, name: 'apple' },
    { id: 2, name: 'pineapple' },
    { id: 3, name: 'orange' },
    { id: 4, name: 'berry' },
]

const lands = [
    { landOwnerId: 6, landId: 1, landTypeID: 1, area: 3800 },
    { landOwnerId: 1, landId: 3, landTypeID: 4, area: 6500 },
    { landOwnerId: 5, landId: 3, landTypeID: 2, area: 9000 },
    { landOwnerId: 2, landId: 2, landTypeID: 3, area: 6600 },
    { landOwnerId: 3, landId: 1, landTypeID: 1, area: 980 },
    { landOwnerId: 5, landId: 2, landTypeID: 2, area: 5900 },
    { landOwnerId: 3, landId: 3, landTypeID: 2, area: 1080 },
    { landOwnerId: 2, landId: 3, landTypeID: 3, area: 2220 },
    { landOwnerId: 4, landId: 3, landTypeID: 4, area: 5700 },
    { landOwnerId: 2, landId: 3, landTypeID: 3, area: 8700 },
    { landOwnerId: 3, landId: 2, landTypeID: 2, area: 910 },
    { landOwnerId: 3, landId: 1, landTypeID: 1, area: 1770 },
    { landOwnerId: 2, landId: 2, landTypeID: 2, area: 9860 }
];

Im a new programmer and need to make an array with the name of type of crop sorted from largest to smallest according to the total sum of the area of each one.

In the "lands" array I have tried to and sort by landTypeID and sum the areas to then get the landTypeID and make it match with id from "typeCrop" array and get the name of type of crop to my new array

if the sum of areas where: apples total area 100, pineapples total area 50, orange total area 70, berry total area 80

the expected result: [apple, berry, orange,pineapple]

-o-

I have listed the taxnumber of landowners but cant get the data to sort the lands by type of crop

function listIDLandOwnerByName() {
    landOwners.sort(function(a, b) {
        if (a.name < b.name)
            return -1;
        if (a.name > b.name)
            return 1;
        return 0;
    })
    return landOwners.map((landOwner) => landOwner.taxNumber);
};
console.log(listIDLandOwnerByName());



Solution

  • It's a classic map-reduce problem, so I have used the same. Then at the end, I made a custom sort comparison.

    const typeCrop = [
        { id: 1, name: 'apple' },
        { id: 2, name: 'pineapple' },
        { id: 3, name: 'orange' },
        { id: 4, name: 'berry' },
    ]
    
    const lands = [
        { landOwnerId: 6, landId: 1, landTypeID: 1, area: 3800 },
        { landOwnerId: 1, landId: 3, landTypeID: 4, area: 6500 },
        { landOwnerId: 5, landId: 3, landTypeID: 2, area: 9000 },
        { landOwnerId: 2, landId: 2, landTypeID: 3, area: 6600 },
        { landOwnerId: 3, landId: 1, landTypeID: 1, area: 980 },
        { landOwnerId: 5, landId: 2, landTypeID: 2, area: 5900 },
        { landOwnerId: 3, landId: 3, landTypeID: 2, area: 1080 },
        { landOwnerId: 2, landId: 3, landTypeID: 3, area: 2220 },
        { landOwnerId: 4, landId: 3, landTypeID: 4, area: 5700 },
        { landOwnerId: 2, landId: 3, landTypeID: 3, area: 8700 },
        { landOwnerId: 3, landId: 2, landTypeID: 2, area: 910 },
        { landOwnerId: 3, landId: 1, landTypeID: 1, area: 1770 },
        { landOwnerId: 2, landId: 2, landTypeID: 2, area: 9860 }
    ];
    
    const groupByCrop=typeCrop.map(c=>(
    {name:c.name,totalArea:lands.reduce((prev,curr)=>curr.landTypeID===c.id?prev+curr.area:prev,0)}
    ))
    const cropsSorted=groupByCrop.sort((a,b)=>a.totalArea>b.totalArea?1:-1).map(crop=>crop.name);
    console.log(cropsSorted);