-1

Say I have the following array of persons:

const array = [{name: 'Glenn'}, {name: 'Rob'}, {name: 'Ronald'}]

And I want to find a certain person in this array, and put it as the first index in the array if it exist, like so:

// Rob is now first index
const array = [{name: 'Rob'}, {name: 'Glenn'}, {name: 'Ronald'}]

How can I achieve this? I can think of all kind of things, like using a find method and save the record if it exists and then removing it from the array and use the unshift method to set it as first index but this sounds kinda complex to me.

Preferably a ES6+ solution, and if the item doesn't exist I want to do nothing.

Giesburts
  • 6,879
  • 15
  • 48
  • 85

4 Answers4

1

You could sort the array.

This approach moves all objects with the wanted name to top.

const
    array = [{ name: 'Glenn' }, { name: 'Rob' }, { name: 'Ronald' }],
    first = 'Rob';

array.sort((a, b) => (b.name === first) - (a.name === first));

console.log(array);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

I am assuming sorting is too expensive to do here since it'll be slow for large arrays. There are two O(n) approaches you can take.

You can use a combination of .splice and findIndex if you want to mutate the original array or .filter with .concat for a non-mutating solution.

I'll show the mutating alternative since it's more effective in large arrays. Note you can always .slice to make it non-mutative and (shallow) clone the array:

const array = [{name: 'Glenn'}, {name: 'Rob'}, {name: 'Ronald'}];
// find the first index matching a predicate
const robIndex = array.findIndex(x => x.name === 'Rob');
if (robIndex) {
  const [ rob ] = array.splice(robIndex, 1); // delete Rob
  array.unshift(rob); // add at first index
}
console.log(array);
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
0

Maybe with something like this:

const array = [{name: 'Glenn'}, {name: 'Rob'}, {name: 'Ronald'}]
  console.log(array.sort((f,s) => f.name == "Rob" ? -1 : 1))
Alberto Sinigaglia
  • 12,097
  • 2
  • 20
  • 48
0

Maybe a simple loop is just as viable:

let array = [{name: 'Glenn'}, {name: 'Rob'}, {name: 'Ronald'}];

function findAndReplace(arr, name2Shift) {
  const workingCopy = [...arr];
  // note: if you don't mind changing the original arr
  // ditch newArr, modify arr and return that
  const newArr = [...arr];
  
  workingCopy.forEach((el, i) => {
    if (el.name === name2Shift) {
      newArr.unshift(newArr.splice(i, 1).shift());
    }
  });
  
  return newArr;
}
// modified
console.log(JSON.stringify(findAndReplace(array, "Rob")));
// no modification
console.log(JSON.stringify(findAndReplace(array, "Pete")));

But a oneliner is also possible (using findIndex here)

let array = [{name: 'Glenn'}, {name: 'Rob'}, {name: 'Ronald'}];
let robComesFirst = array
  .splice(array.findIndex(v => v.name === "Rob"), 1)
  .concat(array);
console.log(JSON.stringify(robComesFirst));
KooiInc
  • 119,216
  • 31
  • 141
  • 177