williamwmy
williamwmy

Reputation: 321

How to filter a Array of objects but change order

Lets say I have an array of objects[] and an array of numbers.

let objects = [
{name: apple, id:1},
{name: banana, id:2},
{name: orange, id:5}
];

let numbers = [5, 1];

I want to filter the object array, so only the id that matches with the numbers stays, and the order should be changed to match the numbers array.

result should be [{name: orange, id:5} , {name: apple, id:1} ]

Can I do it with javascript object prototypes? or can I use 3rd party tools like lodash ?

I've tried with code bellow, but it keeps the order of the original list:

result = object.filter(p => {
    return numbers.includes(parseInt(p.id));
});

Upvotes: 1

Views: 1614

Answers (4)

Nina Scholz
Nina Scholz

Reputation: 386680

You could map the wanted items by finding the objects.

var objects = [{ name: 'apple', id: 1 }, { name: 'banana', id: 2 }, { name: 'orange', id: 5 }],
    numbers = [5, 1],
    result = numbers.map(id => objects.find(o => o.id === id));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

A canonical solution for finding and reordering could be to use a hash table or Map with a fas access of O(1) and map the wanted parts.

For examle here a solution with an abstraction of the key byhanding over the original data array, an array of wanted values and the key.

const
    getObjects = (data, values, key) => values.map(
        Map.prototype.get,
        objects.reduce((m, o) => m.set(o[key], o), new Map)
    ),
    objects = [{ name: 'apple', id: 1 }, { name: 'banana', id: 2 }, { name: 'orange', id: 5 }],
    values = ['banana', 'apple', 'orange'],
    result = getObjects(objects, values, 'name');

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Wicar C
Wicar C

Reputation: 21

It keeps the order because you iterate over objects. If you want to use the order from numbers you have to iterate over numbers.

You didn't say if the ids in numbers had to exist in objects, my solution works even if a stray id finds its way into numbers

let result = []
numbers.forEach(
        element => { if (objects.find(anObject => anObject.id == element))
                         result.push(objects.find(anObject => anObject.id == element)) })

Upvotes: 2

Najam Us Saqib
Najam Us Saqib

Reputation: 3402

checkObject(obj, arr) {
 let x;
 for (x in arr) {
    if(arr[x].id == obj.id){
      return true;
     }
 }
 return false;
}

let items = [{name: 'apple', id:1}, {name: 'banana', id:2}, {name: 'orange', id:5}]
let numbers = [5, 1];
checkObject(items, numbers);

you can try this function to check if your numbers array matches in your array of Object.

Upvotes: 0

nicholaswmin
nicholaswmin

Reputation: 22959

Just Array.map and Array.find. You don't need to Array.filter.

const items = [{name: 'apple', id:1}, {name: 'banana', id:2}, {name: 'orange', id:5}]

const numbers = [5, 1]

const result = numbers.map(n => items.find(i => i.id === n))

console.log(result)

Since you're mapping over numbers, the order of the result Array is identical to numbers.

Upvotes: 2

Related Questions