0

Given an array and variable as following..

array = ['complete','in_progress','planned'];
value = 'planned';

I want to sort the array always starting with the 'value' variable the output should display.

array = ['planned','in_progress','complete'];

eg.

array = ['complete','in_progress','planned'];
value = 'in_progress';

output would be...

array = ['in_progress','complete','planned'];

I tried different ways but I failed to come with a decent solution. Any clean and short ideas?

1
  • 1
    In the first example, why is "complete" moved to the end? It is neither keeping the original relative position nor is it sorted alphabetically Commented Oct 25, 2019 at 6:46

2 Answers 2

2

You can sort and give higher priority to value - if it matches one of the arguments, then it will be sorted before anything. If neither of the two items is value, then just sort normally.

const array = ['complete','in_progress','planned'];
const value = 'in_progress';

array.sort((a, b) => {
  //a comes first
  if (a == value) return -1;
  //b comes first
  if (b == value) return 1;
  
  //neither matches `value` - compare them normally
  return a.localeCompare(b);
});

console.log(array);

And this is the shorter version of the same by (somewhat) abusing type coercion:

const array = ['complete','in_progress','planned'];
const value = 'in_progress';

array.sort((a,b) => ((a == value) * -1) || b == value || a.localeCompare(b));

console.log(array);

Sign up to request clarification or add additional context in comments.

Comments

0

From the top of my head you can try

array = ['complete','in_progress','planned'];
target = 'in_progress';

const answer = array.filter((element) => element !== target)
    .sort()
    .reduce((accumulator, value) => [...accumulator, value], [target]);

edit: I forgot it needs to be sorted.

2 Comments

Why reduce? I don't think adding a value to the front of the array is the time and place for this method. You can use unshift to add to the front. If you really want to do it in one continuous operation, then why not just [target].concat(/* filter + sort */)? That's not that great, either but at least it's not using reduce for an operation that is so trivial.
Yes, concat is much better actually for this problem. First thing that came to mind was to use reduce.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.