1

This is an example of my array :

[
 1: { name: 'blablabla', difficulty: 'A2' },
 2: { name: 'bla', difficulty: 'A1' },
 3: { name: 'blablablabla', difficulty: 'B1' },
 4: { name: 'blablablabla', difficulty: 'B2' },
 5: { name: 'blablablabla', difficulty: 'A2' }
]

my_level: 'B2'

I want to sort the array so that my level of difficulty is the first item, i tried to use sort() but it's only to sort by 'ASC' or 'DESC', anyone have an idea of how to do it ? Thanks !

5
  • What do you mean by "the remaining items are not sorted"? Do you just want to move the fourth item to the front? Commented Apr 14, 2021 at 8:42
  • you want to sort by name or difficulty? Commented Apr 14, 2021 at 8:42
  • 1
    So you just want all elements with difficulty === my_level to be in the beginning of the array? Commented Apr 14, 2021 at 8:42
  • Have a look at stackoverflow.com/questions/1129216/… Commented Apr 14, 2021 at 8:43
  • I just want that the first item difficulty is equal to my level Commented Apr 14, 2021 at 8:43

3 Answers 3

4

You could sort by checking the value of difficulty with the wanted difficulty.

This approach moves the wanted value to top of the array.

const
    array = [{ name: 'blablabla', difficulty: 'A2' }, { name: 'bla', difficulty: 'A1' }, { name: 'blablablabla', difficulty: 'B1' }, { name: 'blablablabla', difficulty: 'B2' }, { name: 'blablablabla', difficulty: 'A2' }]
    difficulty = 'B2';

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

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

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

Comments

3

There's no need to sort it:

arr = [
 { name: 'blablabla', difficulty: 'A2' },
 { name: 'bla', difficulty: 'A1' },
 { name: 'blablablabla', difficulty: 'B1' },
 { name: 'blablablabla', difficulty: 'B2' },
 { name: 'blablablabla', difficulty: 'A2' },
 { name: 'one more', difficulty: 'B2' },
]

my_level = 'B2'

newArr = [
    ...arr.filter(x => x.difficulty === my_level),
    ...arr.filter(x => x.difficulty !== my_level),
    ]

console.log(newArr)

Advantages: 1) faster (I guess), 2) doesn't change the order, 3) doesn't break the original array

Here's some generic (and even faster) code:

// split array into two parts:
// part 0 - where predicate is false
// part 1 - where predicate is true

function partition(ary, predicate) {
    let parts = [[], []];
    for (let x of arr)
        parts[predicate(x) ? 1 : 0].push(x);
    return parts;
}

//

newArr = [].concat(...partition(arr, x => x.difficulty !== my_level))

2 Comments

Heh, I had a similar idea but .slice()-ing around the item index. Which would have added an undefined if the item wasn't found so, .filter() is probably the more robust approach for an immutable shifting of an item to the front.
@VLAZ: yep, if there's only one of them, we could just splice it out... But I hate splices ;)
2

Provide a compare function to sort that takes in two parameters lets say a and b, and returns a value based on the following table.

a.difficulty === desired b.difficulty === desired Value returned by compare
true true 0
true false -1
false true 1
false false 0

const 
  data = [
    { name: "blablabla", difficulty: "A2" },
    { name: "bla", difficulty: "A1" },
    { name: "blablablabla", difficulty: "B1" },
    { name: "blablablabla", difficulty: "B2" },
    { name: "blablablabla", difficulty: "A2" },
  ],
  desired = "B2",
  table = { true: { true: 0, false: -1 }, false: { true: 1, false: 0 } },
  sortedData = [...data].sort(
    (a, b) => table[a.difficulty === desired][b.difficulty === desired]
  );

console.log(sortedData);

1 Comment

Just a tip - if you don't like nested conditional statements (like me...) you can encode the results into a table and just lookup based on a boolean: demo. Although, honestly, it's still a bit ugly. Whitespace formatting only helps so much. However, it might be useful if the nested conditionals are more complex and you start having even more branches.

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.