views:

41

answers:

3

I've been pounding my head on the wall trying to figure out how to sort this in JavaScript (I have to work with it in this format unfortunately).

I need to sort it based on Small, Medium, Large, XL, XXL (Small ranking the highest) in each variationValues size field. The problem is that I need to sort the variationCosts and variationInventories at the same time to match the new order (since each value in order corresponds to the values in the other fields :(

Input I have to work with

var m = {
 variationNames: ["Length", "Size"  ],
 variationValues: [
  ["26.5\"", "XXL"], 
  ["25\"", "Large"], 
  ["25\"", "Medium"], 
  ["25\"", "Small"], 
  ["25\"", "XL"], 
  ["25\"", "XXL"], 
  ["26.5\"", "Large"], 
  ["26.5\"", "Small"], 
  ["26.5\"", "XL"]
 ],
 variationCosts: [
  20.00, 
  20.00, 
  20.00, 
  20.00, 
  20.00, 
  20.00, 
  20.00, 
  20.00, 
  20.00
 ],
 variationInventories: [
  10, 
  60, 
  51, 
  10, 
  15, 
  10, 
  60, 
  10, 
  15
 ],
 parentCost: 20.00
};

Desired output

var m = {
 variationNames: ["Length", "Size"  ],
 variationValues: [
  ["25\"", "Small"],
  ["26.5\"", "Small"],
  ["25\"", "Medium"],
  ["25\"", "Large"],
  ["26.5\"", "Large"],
  ["25\"", "XL"],
  ["26.5\"", "XL"]
  ["25\"", "XXL"],
  ["26.5\"", "XXL"],
 ],
 variationCosts: [
  20.00,
  20.00,
  20.00,
  20.00,
  20.00,
  20.00,
  20.00,
  20.00,
  20.00
 ],
 variationInventories: [
  10,
  10,
  51,
  60,
  15,
  15, 
  15,
  10,
  10
 ],
 parentCost: 20.00
};
+1  A: 

Can you rearrange your data structure? It would be easier if you stored the related data together. For example:

var variations = [
    { length: '25"',   size: "Small",  cost: 20.00, inventory: 10 },
    { length: '26.5"', size: "Small",  cost: 20.00, inventory: 10 },
    { length: '25"',   size: "Medium", cost: 20.00, inventory: 51 },
    { length: '25"',   size: "Large",  cost: 20.00, inventory: 60 },
    { length: '26.5"', size: "Large",  cost: 20.00, inventory: 15 },
    { length: '25"',   size: "XL",     cost: 20.00, inventory: 15 },
    { length: '26.5"', size: "XL",     cost: 20.00, inventory: 15 },
    { length: '25"',   size: "XXL",    cost: 20.00, inventory: 10 },
    { length: '26.5"', size: "XXL",    cost: 20.00, inventory: 10 }
];

variations.sort(
    function(v1, v2) {
        return compareSizes(v1.size, v2.size);
    }
);

(For a suitable definition of compareSizes().)

John Kugelman
Better yet, rearrange it to this order, sort it, then put it back into the desired structure.
Gabe
A: 

You should consider turning those arrays into one array of objects/hashes. Or, failing that, you can use the decorate-sort-undecorate pattern. In this case, you would zip your two related arrays together, sort them, and then unzip them.

Nick Lewis
+2  A: 

I think you're going to need an intermediate array where you consolidate what's essentially a record with its fields spread across a few arrays into a list of objects.

m._tmpRecordList = [];
for(var i=0, z=m.variationValues.length; i<z; i++) {
  m._tmpRecordList.push({
    length: m.variationValues[i][0],
    size: m.variationValues[i][1],
    cost: m.variationCosts[i],
    inventories: m.variationInventories[i]
  });
}

Then write a "size" comparison function:

function sizecmp(sizeA,sizeB) {
   var nA = sizecmp.table[sizeA], nB = sizecmp.table[sizeB];
   if(nA == nB) 
     return 0;
   else if(nA < nB)
     return -1;
   else if(nA > nB)
     return 1;
   else
     throw "bad size value passed to sizecmp";
}
sizecmp.table = { Small: 5, Medium: 4, Large: 3, XL: 2, XXL: 1 }

And then a "record" comparison function using the sizecmp function:

function recordcmp(recA,recB) {
   return sizecmp(recA.size,recB.size);
}

And then:

m._tmpRecordList.sort(recordcmp);

Translating m._tmpRecordList back to the unfortunate structure you're stuck with is left as an exercise for the reader. :)

Weston C