Home > front end >  How to insert elements into specific index in a 2D array in javascript?
How to insert elements into specific index in a 2D array in javascript?

Time:12-25

I have an object that looks like below

const tableData = [
    {
        
        "Location": "London",
        "Status": "Unknown"
    },
    {
        
        "Location": "Delhi",
        "Status": "Reachable"
    },
    {
        
        "Location": "Berlin",
        "Status": "Unknown"
    },
    {
        
        "Location": "Tokyo",
        "Status": "Busy"
    },
]

Now I want to create a 2D array which will hold this information in a certain way. Here is my code below

const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2}
let statusOrderInfo = Array(Object.keys(statusOrder).length).fill([]);
for(let i=0; i< tableData.length; i  ) {
    const status = tableData[i]["Status"].trim()
    const statusIndex = statusOrder[status]
    statusOrderInfo[statusIndex].push(tableData[i])
}
console.log(statusOrderInfo)

As you can see I want each item of the tableData object to be in a certain index of the 2D array. So the item that contains Status as Reachable should be at index 0, the item that contains the Status as Busy should be at index 1 and so on.

So the final output should look like

[
   [
      {
         "Location":"Delhi",
         "Status":"Reachable"
      }
   ],
   [
      {
         "Location":"Tokyo",
         "Status":"Busy"
      }
   ],
   [
      {
         "Location":"London",
         "Status":"Unknown"
      },
      {
         "Location":"Berlin",
         "Status":"Unknown"
      }
   ]
]

But I get a wrong output on running the above code even though I am targeting the correct index. What's wrong in my approach?

CodePudding user response:

Using Array#reduce:

const 
  tableData = [ { "Location": "London", "Status": "Unknown" }, { "Location": "Delhi", "Status": "Reachable" }, { "Location": "Berlin", "Status": "Unknown" }, { "Location": "Tokyo", "Status": "Busy" } ],
  statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2};

const statusOrderInfo = tableData.reduce((list, e) => {
  const index = statusOrder[e.Status];
  list[index] = [...(list[index] || []), {...e}];
  return list;
}, []);

console.log(statusOrderInfo);

CodePudding user response:

Simple fix on your problem is that just changing your manner to set initial value of statusOrderInfo and use Array.from instead of Array.fill like this:

let statusOrderInfo = Array.from({length: Object.keys(statusOrder).length}, ()=> []);

another solution is set initiali value of statusOrderInfo by empty array, and then in your for loop, after you get the index of current object based on status value, you can check if statusIndex already exist in the statusOrderInfo or not, like this:

const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2}
let statusOrderInfo = [];
for(let i=0; i< tableData.length; i  ) {
    const status = tableData[i]["Status"].trim()
    const statusIndex = statusOrder[status];
    if(statusOrderInfo[statusIndex]) statusOrderInfo[statusIndex].push(tableData[i]);
    else statusOrderInfo[statusIndex] = [ tableData[i] ]
}
console.log(statusOrderInfo);

another solution, is to use reduce method on array, like this:

const tableData = [{

    "Location": "London",
    "Status": "Unknown"
  },
  {

    "Location": "Delhi",
    "Status": "Reachable"
  },
  {

    "Location": "Berlin",
    "Status": "Unknown"
  },
  {

    "Location": "Tokyo",
    "Status": "Busy"
  },
];
const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2}
const result = tableData.reduce((acc, cur) => {
  const index = statusOrder[cur.Status];
  if (acc[index]) acc[index].push(cur);
  else acc[index] = [cur]
  return acc;
}, []);
console.log(result)

CodePudding user response:

Anoter one solution in kind of declartive way:

First of all sort objects by status code using Array#sort

And then just wrap every object to it own array using Array#map

const tableData = [{Location: "London",Status: "Unknown"},{Location: "Delhi",Status: "Reachable"},{Location: "Berlin",Status: "Unknown"},{Location: "Tokyo",Status: "Busy"}]
const statusOrder = {Reachable: 0, Busy: 1, Unknown: 2}

const result = tableData
  .sort(({ Status: s1 }, { Status: s2 }) => statusOrder[s1] - statusOrder[s2])
  .map((item) => [item]);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

CodePudding user response:

As others explained, reduce would be the best choice for your scenario. Because on every iteration you would create a new Array object.

const tableData = [{ Location: "London", Status: "Unknown" }, { Location: "Delhi", Status: "Reachable" }, { Location: "Berlin", Status: "Unknown" }, { Location: "Tokyo", Status: "Busy" }]
const statusOrder = { "Reachable": 0, "Busy": 1, "Unknown": 2 };

const statusOrderInfo = tableData.reduce((accumulator, currentValue) => {
  const index = statusOrder[currentValue.Status];
  if (accumulator[index]) {
    accumulator[index].push(currentValue);
  } else {
    accumulator[index] = [currentValue];
  }
  return accumulator;
}, []);

console.log(statusOrderInfo);

Explanation for what's going on in your code:

As you have used [].fill([]) to fill the Array. It would create only one empty Array object and use it to initialize the actual array. That's why the following snippet behaves the way it should behave :)

const statusOrderInfo = Array(3).fill([]);
statusOrderInfo[0].push(10);

console.log(statusOrderInfo);
/* Results:
[
  [ 10 ],
  [ 10 ],
  [ 10 ]
]
*/
  • Related