Hello Mellow
Hello Mellow

Reputation: 169

Efficient algorithm to order objects nested in an array

It seems easy enough but when I think of how I would write it, it turns into some big mess and I want it to be as efficient as possible (within a reasonable amount at least). I also have two questions pertaining to this problem.

1) So I have an array of objects that look like this

[{id: apple, position: 0},{id: orange, position: 1},{id: banana, position: 2}]

But the position is not guaranteed to be in order, like this

[{id: apple, position: 2},{id: orange, position: 0},{id: banana, position: 1}]

And I'd like the algorithm to loop through the array and grab the id's in ascending order based on the positions, naturally I'd want to do something with the id I receive in the loop, so I could have some sort of loop and within the loop print out 'I ate' + id so it would come out as

I ate orange
I ate banana
I ate apple

2) Think of this as a different scenario but using the same data structure as before

[{id: apple, position: 0},{id: orange, position: 1},{id: banana, position: 2}, {id: grape, position: 4}, {id: mango, position: 3}]

And I take out the object with id orange so it looks like this

[{id: apple, position: 0},{id: banana, position: 2}, {id: grape, position: 4}, {id: mango, position: 3}]

But now the positions don't make sense because there's 0 -> 2 -> 3 -> 4 but no position 1, so I'd like to put them back in proper ascending order (It must hold the same sequence, so it still has to go apple -> banana -> mango -> grape) so it turns into

[{id: apple, position: 0},{id: banana, position: 1}, {id: grape, position: 3}, {id: mango, position: 2}]

How would I do this best as well?

Note: There could be a scenario where I have to take out more than one object, but I guess it doesn't matter since I can just sequentially do it or something.

Thanks!

Upvotes: 0

Views: 144

Answers (3)

p u
p u

Reputation: 1445

amm..too late to post! but hope it may help others!..i have merged all in same function :)

var arr = [{
    id: 'apple',
    position: 0
}, {
    id: 'banana',
    position: 2
}, {
    id: 'grape',
    position: 4
}, {
    id: 'grapeeee',
    position: 5
}]
var old = 0,
    next = 1;
arr.sort(function(a, b) {

    if (old != a.position) {
        a.position = old;
    }
    if (next != b.position) {
        b.position = next;
    }

    var keyA = a.position,
        keyB = b.position;
    console.log(keyA, "--", keyB)
    old++;
    next++;

    if (keyA < keyB) return -1;
    if (keyA > keyB) return 1;
    return 0;

});
console.log("arr--", arr);
for (var i = 0; i < arr.length; i++) {
    console.log("I ate ", arr[i].id)
}

Upvotes: 0

ic3b3rg
ic3b3rg

Reputation: 14927

I broke this out into

  1. Sorting
  2. Position recalculation
  3. Working with sorted fruit

const fruit = [{id: "apple", position: 0},{id: "banana", position: 2}, {id: "grape", position: 4}, {id: "mango", position: 3}];

// 1. Sort the fruit by position
fruit.sort((a, b) => a.position - b.position);

console.log(fruit)

// 2. Recalculate position
fruit.forEach((o, idx) => {
  o.position = idx;
});

console.log(fruit)

// 3. Work with the sorted fruit
console.log(fruit.map(({ id }) => `I ate ${id}`))

Upvotes: 3

Code Maniac
Code Maniac

Reputation: 37755

You can do it with sort and map

let arr = [{id: 'apple', position: 2},{id: 'orange', position: 0},{id: 'banana', position: 1}];
let op = arr.sort((a,b)=> a.position-b.position).map(e=> `I ate ${e.id}`);

console.log(op)

Upvotes: 0

Related Questions