3

How could i sort e.g an array like this one:

[
  '<@520968882077433856> is level **7,64** _(18115.5 total xp)_',
  '<@289037609274048513> is level **7,07** _(14473 total xp)_',
  '<@672835870080106509> is level **8,25** _(22473.5 total xp)_',
  '<@536686935134175254> is level **6,22** _(10184.5 total xp)_',
]

I would like to sort it by the amount of total xp, so the number within the brackets.

5 Answers 5

1

You can use the sort callback. Extract the number with a regular expression:

const data = [
  '<@520968882077433856> is level **7,64** _(18115.5 total xp)_',
  '<@289037609274048513> is level **7,07** _(14473 total xp)_',
  '<@672835870080106509> is level **8,25** _(22473.5 total xp)_',
  '<@536686935134175254> is level **6,22** _(10184.5 total xp)_',
];

const regex = /(?<=_\()[\d.]+/;
data.sort((a, b) => +a.match(regex) - +b.match(regex));
console.log(data);

The + is used to convert the returned array (with one match element) to a string and then that to a number. You could use ?.[0] to actually get that first array element.

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

2 Comments

This could fail should some (unshown) entries happen to have more than one decimal number.
That could, but it requires that the decimal number follows the literal _(. Seems quite a strong condition already. And in that case the first gets precedence.
1

Here is another try, looking for a space after the number:

const arr=[
  '<@520968882077433856> is level **7,64** _(18115.5 total xp)_',
  '<@289037609274048513> is level **7,07** _(14473 total xp)_',
  '<@672835870080106509> is level **8,25** _(22473.5 total xp)_',
  '<@536686935134175254> is level **6,22** _(10184.5 total xp)_',
];

function getN(s){
 return s.match(/_\((.+?) /)[1];
}
arr.sort((a,b)=>getN(a)-getN(b))

console.log(arr)

Comments

1

We can try sorting using a custom lambda expression:

var input = [
    '<@520968882077433856> is level **7,64** _(18115.5 total xp)_',
    '<@289037609274048513> is level **7,07** _(14473 total xp)_',
    '<@672835870080106509> is level **8,25** _(22473.5 total xp)_',
    '<@536686935134175254> is level **6,22** _(10184.5 total xp)_',
];
var output = input.sort( (a, b) => parseFloat(a.match(/(\d+(?:\.\d+)?) total xp\b/)[1]) - parseFloat(b.match(/(\d+(?:\.\d+)?) total xp\b/)[1]));
console.log(output);

In the above we are extracting the number which is followed by total xp, parsing it as a float, and then using that value in the sorting comparator. If you want descending order, then just reverse the inequality in the lambda function.

1 Comment

0

Please try this.

const array = [
    "<@520968882077433856> is level **7,64** _(18115.5 total xp)_",
    "<@289037609274048513> is level **7,07** _(14473 total xp)_",
    "<@672835870080106509> is level **8,25** _(22473.5 total xp)_",
    "<@536686935134175254> is level **6,22** _(10184.5 total xp)_",
];

const extractDigitNumber = (string) => {
    return string.match(/(?<=\_\()(.*?)(?=\)\_)/)[0].replace(/[^\d\.]+/g, '') 
}

array.sort((a, b) => {
    return extractDigitNumber(a) - extractDigitNumber(b)
})

console.log(array)

Comments

0

Details are commented in example

let data = [
  '<@520968882077433856> is level **7,64** _(18115.5 total xp)_',
  '<@289037609274048513> is level **7,07** _(14473 total xp)_',
  '<@672835870080106509> is level **8,25** _(22473.5 total xp)_',
  '<@536686935134175254> is level **6,22** _(10184.5 total xp)_',
]

/*
* - .map() through array 
* - on every iteration run .match() using this regex:
*   /(\d+\.?\d*)(?=\stotal)/ which means:
    "match one or more numbers, then a possible dot,
    and then possible numbers, but only if it's followed
    by a space and literal 'total'"
* - return a match in an array and the current index
* - .sort() the sub-arrays by their first index (sub[0])
*/
let indices = data.map((str, idx) => [+str.match(/(\d+\.?\d*)(?=\stotal)/g), idx]).sort((a, b) => a[0] - b[0]);
console.log(JSON.stringify(indices));

//Define an empty array
let result = [];
/*
* - run new array of arrays with .forEach()
* - get the string within the original array (data) by
    the current sub-array's second index (sub[1])
* - push the value into the empty array (result)
*/
indices.forEach((sub, idx) => result.push(data[sub[1]]));
console.log(result);

Comments

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.