0

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"
    }
  }
]
4
  • 4
    Looks to me as if it should be b.something.weight - a.something.weight Commented Aug 25, 2015 at 14:22
  • Separately: "Apparently JSON.stringify does not preserve the order of objects". It can't. Javascript object properties don't have an order to preserve, Commented Aug 25, 2015 at 14:27
  • 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. it works fine if you change that: jsfiddle.net/s4k3t1Lo Commented Aug 25, 2015 at 14:27
  • @JKirchartz Correct objArray. error was introduced during simplification for presentation here. - OP Commented Aug 25, 2015 at 14:39

2 Answers 2

1

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>');

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

2 Comments

Not quite. I need it in descending order. But you were half right in that I was omitting "something" from "return a.something.weight - b.something.weight" So this works: "byWeight.sort(function (a, b) { return b.something.weight - a.something.weight; });"
I don't think you should have deleted the explanation.
0

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);

3 Comments

Halfway there, but how does that solve the sorting problem?
This does not solve the sorting problem; it still has the exact same bug.
I introduced an error in the array object while simplifying it for presentation here. Corrected -- OP

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.