4

I have an object array like

array[0] = {id: 1, name: "First"}
array[1] = {id: 2, name: "Second"}

Which I've tried to sort by name field by using:

Array.prototype.alphanumSort = function (caseInsensitive) {
for (var z = 0, t; t = ((typeof this[z] == "string" || typeof this[z] == "undefined") ? this[z] : this[z].name); z++) {
    this[z] = new Array();
    var x = 0, y = -1, n = 0, i, j;

    while (i = (j = t.charAt(x++)).charCodeAt(0)) {
        var m = (i == 46 || (i >= 48 && i <= 57));
        if (m !== n) {
            this[z][++y] = "";
            n = m;
        }
        this[z][y] += j;
    }
}

this.sort(function (a, b) {
    for (var x = 0, aa, bb; (aa = a[x]) && (bb = b[x]); x++) {
        if (caseInsensitive) {
            aa = aa.toLowerCase();
            bb = bb.toLowerCase();
        }
        if (aa !== bb) {
            var c = Number(aa), d = Number(bb);
            if (c == aa && d == bb) {
                return c - d;
            } else return (aa > bb) ? 1 : -1;
        }
    }
    return a.length - b.length;
});

for (var z = 0; z < this.length; z++)
    this[z] = this[z].join("");
}

but the list that I'm getting back from it contains an array with just the name field from it, without the corresponding id. Why is this happening? Is there a way to apply this algorithm to filter objects? I'm new in JavaScript, so please be gentle.

4
  • 2
    had you have a look to String#localeCompare and the options? Commented Oct 5, 2018 at 7:31
  • please dont put methods on the prototype chain Commented Oct 5, 2018 at 7:31
  • it's OK @AyushGupta - OP never actually USES that code anyway Commented Oct 5, 2018 at 8:12
  • @NinaScholz What if I have situations like 'Ex 10' and 'Ex 2'? The second one should be the first one Commented Oct 5, 2018 at 8:16

3 Answers 3

6

You could use sorting with map and String#localeCompare with options

sensitivity

Which differences in the strings should lead to non-zero result values. Possible values are:

  • "base": Only strings that differ in base letters compare as unequal. Examples: a ≠ b, a = á, a = A.
  • "accent": Only strings that differ in base letters or accents and other diacritic marks compare as unequal. Examples: a ≠ b, a ≠ á, a = A.
  • "case": Only strings that differ in base letters or case compare as unequal. Examples: a ≠ b, a = á, a ≠ A.
  • "variant": Strings that differ in base letters, accents and other diacritic marks, or case compare as unequal. Other differences may also be taken into consideration. Examples: a ≠ b, a ≠ á, a ≠ A.

The default is "variant" for usage "sort"; it's locale dependent for usage "search".

numeric

Whether numeric collation should be used, such that "1" < "2" < "10". Possible values are true and false; the default is false. This option can be set through an options property or through a Unicode extension key; if both are provided, the options property takes precedence. Implementations are not required to support this property.

var array = ['Ex 10', 'Ex 2', 'a 10.1', 'a 1.1', 'a 10.0', 'a 2.0'];

array.sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }));

console.log(array)

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

Comments

3

You can use String.prototype.localeCompare

var arr = [
  {id: 1, name: "Third"},
  {id: 2, name: "Fifth"},
  {id: 3, name: "Second"},
  {id: 4, name: "Fourth"},
  {id: 5, name: "First"}
];

arr.sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: 'base' }));

console.log(arr);

7 Comments

In situations like sorting names like 'First 10' and 'First 2', the second one should be first
If there was no name property in some object, your code would compare other strings with string "undefined"
In that case i would suggest making a custom function to compare two strings which returns 1, -1, 0 to Array.sort() as suggested below by vizsatiz. I will try to do it and update my answer if i get some free time.
@PR7 there's no need for custom function, see other answer
@Dana There is no need to write a custom compare function. You can use the options in localeCompare function. I have updated my answer. barbsan Thanks :)
|
0

Here is an example using Lodash (https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js):

array[0] = {id: 1, name: "First"}
array[1] = {id: 2, name: "Second"}
array = _.orderBy(array, 'name', 'desc')

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.