4
\$\begingroup\$

I want to move two element of my array to the beginning. This solution works but I would like to know a better approach since using sort() twice is probably not the best.

Array Input:

colors = [{name: yellow}, {name: blue}, {name: green}, {name: red}, {name: orange}]

JS Function:

sort(){
let green= colors.find(color=> color.name === "green")
let red= colors.find(color=> color.name === "red")

colors.sort(function(x,y){ return x == red? -1 : y == red? 1 : 0; });
colors.sort(function(x,y){ return x == green? -1 : y == green? 1 : 0; });
}

Output:

colors = [{name: green}, {name: red}, {name: yellow}, {name: blue}, {name: orange}]

PS: I want green to always the above red

\$\endgroup\$
2
  • \$\begingroup\$ Do you care about the ordering of the other colors? \$\endgroup\$ – Ted Brownlow Aug 31 '20 at 14:54
  • 2
    \$\begingroup\$ @TedBrownlow yes, the rest of the elements have to maintain the same order as they where before \$\endgroup\$ – user229948 Aug 31 '20 at 14:56
2
\$\begingroup\$

Find the index of the green and red items, then remove them from the array with splice. Then you can make a properly ordered array by combining the removed items with the rest of the items in the original array:

const colors = [{name: 'yellow'}, {name: 'blue'}, {name: 'green'}, {name: 'red'}, {name: 'orange'}]
const removeColor = colorToRemove => (
  colors.splice(
    colors.findIndex(({ name }) => name === colorToRemove),
    1
  )[0]
);
const green = removeColor('green');
const red = removeColor('red');
const newColors = [green, red, ...colors];
console.log(newColors);

Or, without mutation (it's good to avoid mutation when not necessary, it can make code a bit more predictable in most cases):

const colors = [{name: 'yellow'}, {name: 'blue'}, {name: 'green'}, {name: 'red'}, {name: 'orange'}]
const getColor = colorToRemove => colors.find(({ name }) => name === colorToRemove);
const green = getColor('green');
const red = getColor('red');
const newColors = [green, red, ...colors.filter(({ name }) => name !== 'green' && name !== 'red')];
console.log(newColors);

Also note:

  • String literals require delimiters. {name: yellow} won't work - you want {name: 'yellow'}.
  • If you aren't going to reassign a variable name (most of the time you should be able to avoid reassignment), always use const. Only use let when you must reassign.
  • For readability, better to indent your code when entering a new block (such as a function).
\$\endgroup\$
0
\$\begingroup\$

I liked the @CertainPerformance solution, because you just need to find what you need(green and red), put in the order that you want to and just concat with the rest :) This was a good answer, in my humble opinion

But another way to do the same is using an Object with destructuring assigment

That is:

  1. map every object with the color name
  2. find the colors with the key(color name) that you already know and want to order(green and red)
  3. put the others colors in one object with a rest operator
  4. put in the order that you want to

This way, you can avoid to iterate twice every time you want to search for a color

const colors = [{name: 'yellow'}, {name: 'blue'}, {name: 'green'}, {name: 'red'}, {name: 'orange'}]

const sort = colors => {
  const obj = Object.assign(...colors.map(o => ({ [o.name]: o }) ))
  const { green, red, ...others } = obj;

  return [green, red, ...Object.values(others)];
}

console.log(sort(colors));

Notice that I followed the advice of use imutability that @CertainPerformance told, which I agree; in another words, for the same input that this function receive, it will always produce the same result

Useful links:

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.