3

I have an object like this in JavaScript:

myArray[0] -> 0:"62", 1:8, 2:0, 3:"11"
myArray[1] -> 0:"62", 1:8, 2:0, 3:"15"
myArray[2] -> 0:"48", 1:8, 2:0, 3:"04"
myArray[3] -> 0:"48", 1:8, 2:0, 3:"01"
myArray[4] -> 0:"62", 1:8, 2:0, 3:"12"
myArray[5] -> 0:"48", 1:8, 2:0, 3:"02"
myArray[6] -> 0:"62", 1:8, 2:0, 3:"14"
myArray[7] -> 0:"48", 1:8, 2:0, 3:"03"

And I'm trying to make it to be like this:

myArray[0] -> 0:"48", 1:8, 2:0, 3:"01"
myArray[1] -> 0:"48", 1:8, 2:0, 3:"02"
myArray[2] -> 0:"48", 1:8, 2:0, 3:"03"
myArray[3] -> 0:"48", 1:8, 2:0, 3:"04"
myArray[4] -> 0:"62", 1:8, 2:0, 3:"11"
myArray[5] -> 0:"62", 1:8, 2:0, 3:"12"
myArray[6] -> 0:"62", 1:8, 2:0, 3:"14"
myArray[7] -> 0:"62", 1:8, 2:0, 3:"15"

As you see, I'm trying to sort it by myArray[i][0] at first, and then sort by myArray[i][3] based on the myArray[i][0] as index. I managed to sort by myArray[i][0] using

myObject.sort(function(a, b){ 
    return parseInt(a) - parseInt(b); 
});

How do I accomplish this with no libraries?

9
  • 1
    Try looking at this question - stackoverflow.com/questions/6913512/… Commented Mar 17, 2016 at 17:13
  • Just to check, are you sure you're using an object ({}) or are you rather using an array ([])? When you have numeric keys, you'd generally use an array in javascript. Commented Mar 17, 2016 at 17:15
  • return parseInt(a[0] +a[1] +a[2] +a[3], 10 ) - parseInt(b[0] +b[1] +b[2] +b[3], 10 ); Commented Mar 17, 2016 at 17:15
  • So you check if the a[0] === b[0] and if it is, then you compare a[3] to b[3] in your sort function Commented Mar 17, 2016 at 17:20
  • @user162097 to be honest I'm not an expert in Javascript, so I'm making an array of arrays, but when I get "typeof" is says "object". So I is that correct? Commented Mar 17, 2016 at 17:34

2 Answers 2

6

I suggest to sort in one run with chained comparison functions.

How Array#sort() works:

If compareFunction is supplied, the array elements are sorted according to the return value of the compare function. If a and b are two elements being compared, then:

  • If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.

  • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.

  • If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
  • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If inconsistent results are returned then the sort order is undefined.

In this case the compare function has two groups, one for sorting index [0] and one sorting index [3]. If the value at index [0] is equal, the the sorting for index [3] is taken. Both groups are chained with a logical or ||.

var array = [["62", 8, 0, "11"], ["62", 8, 0, "15"], ["48", 8, 0, "04"], ["48", 8, 0, "01"], ["62", 8, 0, "12"], ["48", 8, 0, "02"], ["62", 8, 0, "14"], ["48", 8, 0, "03"]];

array.sort(function (a, b) {
    return a[0].localeCompare(b[0]) || a[3].localeCompare(b[3]);
});

document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');

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

3 Comments

the use of localeCompare is a bit confusing and might give unwanted results if positions 0 and 3 are actually numeric data, in spite of being strings
if both are numbers, you can use return a[0] - b[0] || a[3] - b[3];
Thanks @NinaScholz . It seems that this solved my problem. Could you do the kindness of explaining exactly what this code does?
2

To me your variable looks like an Array (object indexed with integer keys) so, if it's the case, what about:

var ar = [
  ["62", 8, 0, "11"],
  ["62", 8, 0, "15"],
  ["48", 8, 0, "04"],
  ["48", 8, 0, "01"],
  ["62", 8, 0, "12"],
  ["48", 8, 0, "02"],
  ["62", 8, 0, "14"],
  ["48", 8, 0, "03"]
]

var result =  ar.map(function(a) {
  return {key: a.join(''), val: a}
}).sort(function(a, b){ 
  return parseInt(a.key, 10) - parseInt(b.key, 10);
}).map(function(a) {
  return a.val
})
console.log(result)

See this fiddle

Edit

The Object version:

var data = [{ 0:"62", 1:8, 2:0, 3:"11"},{ 0:"62", 1:8, 2:0, 3:"15"},
            { 0:"48", 1:8, 2:0, 3:"04"},{ 0:"48", 1:8, 2:0, 3:"01"},
            { 0:"62", 1:8, 2:0, 3:"12"},{ 0:"48", 1:8, 2:0, 3:"02"},
            { 0:"62", 1:8, 2:0, 3:"14"},{ 0:"48", 1:8, 2:0, 3:"03"}]

var result =  data.map(function(a) {
  return {key: [0,1,2,3].map(function(k) {return a[k]}).join(''), val: a}
}).sort(function(a, b){ 
  return parseInt(a.key, 10) - parseInt(b.key, 10);
}).map(function(a) {
  return a.val
})
console.log(result)

Updated fiddle

Edit 2

After @malixsys's comment, here's a more efficient way:

var result =  data.sort(function(a, b){ 
  return parseInt(a[0]+ a[1] + a[2] + a[3], 10) - parseInt(b[0]+ b[1] + b[2] + b[3], 10);
})

And corresponding updated fiddle

3 Comments

Mapping, sorting and then mapping again seems horribly inefficient and unnecessary. You can sort it in a single step.
Thank you for the extended explanation. I tried the last solution, but it didn't worked for me.
Hey! That was my comment :) but who cares... Should have written an answer :P well done.

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.