dtburgess
dtburgess

Reputation: 613

javascript: sorting an array of objects derives inconsistent results

I am working to sort an array of objects in descending order using pure javascript. I initially thought that a JSON.stringify method was causing the issue, as described [here][1]. Apparently JSON.stringify does not preserve the order of objects by design. Give the below array of objects I seem to get a random sort order using the following code where I sort the array of objects and then derive the weight property of the first object in the array.

var byWeight = objArray.slice(0);
var sorted = byWeight.sort(function(a,b) { return b.weight - a.weight; } );
sorted[0].something.weight;

On distinct runs of this code, I seem to randomly derive .29 or .35 for the weight. Why is this occurring?

Here is the array:

[
  {
    "something": {
      "terms": [
        {
          "elements": {
            "number": {
              "span": [
                9,
                10
              ],
              "value": "1"
            }
          },
          "span": [
            9,
            12
          ],
          "value": "1g",
          "label": "grams"
        }
      ],
      "span": [
        9,
        12
      ],
      "weight": 0.29,
      "value": "1gm"
    }
  },
  {
    "something": {
      "terms": [
        {
          "elements": {
            "number": {
              "span": [
                16,
                18
              ],
              "value": "30"
            }
          },
          "span": [
            16,
            20
          ],
          "value": "30ml",
          "label": "liters"
        }
      ],
      "span": [
        16,
        20
      ],
      "weight": 0.35,
      "value": "30ml"
    }
  }
]

Upvotes: 0

Views: 200

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386540

You have the wrong reference. Change this

var sorted = byWeight.sort(function(a,b) { return b.weight - a.weight; } );

to (watch .something.)

byWeight.sort(function (a, b) { return b.something.weight - a.something.weight; });

Working model:

var data = [
  {
      "something": {
          "terms": {
              "span": [
              9,
              12
              ],
              "value": "1g",
              "label": "grams"
          }
      ,
          "span": [
          9,
          12
          ],
          "weight": 0.29,
          "value": "1gm"
      }
  },
  {
      "something": {
          "terms": {
              "span": [
              16,
              20
              ],
              "value": "30ml",
              "label": "liters"
          }
      ,
          "span": [
          16,
          20
          ],
          "weight": 0.35,
          "value": "30ml"
      }
  }
];

var sorted = data.slice(0);
sorted.sort(function (a, b) {
    return b.something.weight - a.something.weight; // desc!
});
document.write('<pre>' + JSON.stringify(sorted, 0, 4) + '</pre>');

Upvotes: 1

JKirchartz
JKirchartz

Reputation: 18022

Your objArray is poorly formatted, "terms" shouldn't be an array if it contains key-indexed elements like "span", "value", and "label' it should be an object; then your sort is looking in the wrong place, it should be looking at a.something.weight/b.something.weight instead. jsfiddle.net/3qgtn9r1

var objArray = [
  {
    "something": {
      "terms": {
          "span": [
            9,
            12
          ],
          "value": "1g",
          "label": "grams"
      },
      "span": [
        9,
        12
      ],
      "weight": 0.29,
      "value": "1gm"
    }
  },
  {
    "something": {
      "terms": {
          "span": [
            16,
            20
          ],
          "value": "30ml",
          "label": "liters"
      },
      "span": [
        16,
        20
      ],
      "weight": 0.35,
      "value": "30ml"
    }
  }
];
var byWeight = objArray.slice(0);
var sorted = byWeight.sort(function(a,b) { return a.something.weight - b.something.weight; } );
console.log(sorted[0].something.weight);

Upvotes: 0

Related Questions