Home > Mobile >  Javascript reorder array of nested arrays in particular order
Javascript reorder array of nested arrays in particular order

Time:11-24

I am looking for a way to reorder the beneath array of nested arrays in a specific order. The values within the exposureLevel array come in any order when imported.

var exposureLevel = [["Exposure Level","Number"],["High",15],["Low",38],["Medium",105],["None",156]];

Some of these values can also be missing from the exposureLevel array. Beneath are some possible examples of this:

[["Exposure Level","Number"],["Low",38],["Medium",105]];
[["Exposure Level","Number"],["High",15],["None",156]];
[["Exposure Level","Number"],["High",15],["Medium",105],["None",156]];

I would like the array to be in the order beneath, starting with the [1] element after the heading being None, Low, Medium, High. The three arrays beneath show how I'd like the three examples above to output. I'm not entirely sure how to do this, but I'd have to have some type of check where the string values within the sub-arrays are compared and that entire sub-array's position in the parent array is adjusted.

[["Exposure Level","Number"],["Low",38],["Medium",105]];
[["Exposure Level","Number"],["None",156],["High",15]];
[["Exposure Level","Number"],["None",156],["Medium",105],["High",15]];

I have looked at these posts prior to posting this but haven't had a great deal of success:

  1. For-each over an array in JavaScript
  2. JOLT - Reorder nested arrays
  3. How do I check if an array includes a value in JavaScript?
  4. Javascript array contains/includes sub array

My current solution:

for (let i = 0; i < exposureLevel.length; i  ) {

  if(exposureLevel[i][0] == "None"){
    console.log(exposureLevel[i][0])
  } 
  if(exposureLevel[i][0] == "Low"){
    console.log(exposureLevel[i][0])
  } 
  if(exposureLevel[i][0] == "Medium"){
    console.log(exposureLevel[i][0])
  } 
  if(exposureLevel[i][0] == "High"){
    //not sure how to push onto array correctly
    console.log(exposureLevel[i][0])
  }

}

I understand my current solution doesn't do anything, but I've managed to isolate the string in each sub-array. The next step is to push the entire array into a new array in the specified order. If anyone knows a better way to do the above, please let me know.

I have little experience with JS. If someone could assist me with this or point me in the right direction I'd greatly appreciate it. Please let me know if there's any further information that is needed. Thanks.

CodePudding user response:

Array.sort with mapping of keys to another setting orders

const exposureLevel = [["Exposure Level","Number"],["High",15],["Low",38],["Medium",105],["None",156]];
const orders = { None: 1, Low: 2, Medium: 3, High: 4 };
const sorted = exposureLevel.sort((a, b) => (orders[a[0]] || 0) - (orders[b[0]] || 0));
console.log(sorted);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Reference: Array.sort()

CodePudding user response:

Use an object to define your sort order, and use that in your comparator:

const o = {None: 0, Low: 1, Medium: 2, High: 3};

const sort = ([h, ...v]) => [h, ...v.sort(([l1], [l2]) => o[l1] - o[l2])];

console.log(sort([["Exposure Level","Number"],["Low",38],["Medium",105]]));
console.log(sort([["Exposure Level","Number"],["High",15],["None",156]]));
console.log(sort([["Exposure Level","Number"],["High",15],["Medium",105],["None",156]]));
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Use Array.sort to sort the array.

Logic

  • Make use of a reference array order to keep track of the order of output.
  • Sort the array based on the index of the labels from the reference order array.

const order = ["Exposure Level", "None", "Low", "Medium", "High"];
var exposureLevel = [
  ["Exposure Level","Number"],
  ["High",15],
  ["Low",38],
  ["Medium",105],
  ["None",156],
];
exposureLevel.sort((a, b) => {
  // Should return -1, 0 or  1
  if (order.indexOf(a[0]) > order.indexOf(b[0])) return 1;
  else if (order.indexOf(a[0]) < order.indexOf(b[0])) return -1;
  else return 0;
});
console.log(exposureLevel);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

One Liner Solution

const order = ["Exposure Level", "None", "Low", "Medium", "High"];
const exposureLevel = [["Exposure Level","Number"], ["High",15], ["Low",38], ["Medium",105], ["None",156]];
exposureLevel.sort((a, b) => order.indexOf(a[0]) - order.indexOf(b[0]));
console.log(exposureLevel);
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related