如何在JavaScript中将元素插入到二维数组的特定索引位置?

5

我有一个像下面这样的对象

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

正如您所看到的,我希望将tableData对象的每个条目放置在2D数组的特定索引中。因此,包含StatusReachable的条目应该在索引0处,包含StatusBusy的条目应该在索引1处,以此类推。
因此,最终输出应如下所示:
[
   [
      {
         "Location":"Delhi",
         "Status":"Reachable"
      }
   ],
   [
      {
         "Location":"Tokyo",
         "Status":"Busy"
      }
   ],
   [
      {
         "Location":"London",
         "Status":"Unknown"
      },
      {
         "Location":"Berlin",
         "Status":"Unknown"
      }
   ]
]

但是,尽管我定位了正确的索引,但在运行上述代码时,我得到了错误的输出。我的做法有什么问题?

5个回答

2

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


1

你的问题可以通过改变statusOrderInfo的初始值设置方式并使用Array.from代替Array.fill来简单解决,代码如下:

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

另一个解决方案是通过空数组设置statusOrderInfo的初始值,然后在for循环中,在根据status值获取当前对象的索引后,您可以检查statusIndex是否已经存在于statusOrderInfo中,如下所示:

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

另一个解决方案是在数组上使用reduce方法,像这样:

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)


1
另一种声明性方式的解决方案:
首先使用Array#sort按状态代码对对象进行排序。
然后使用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; }


0
如其他人所解释的那样,reduce 将是您情景下的最佳选择。因为在每次迭代中,您都会创建一个新的 Array 对象。

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

你代码中发生了什么的解释:

你使用了 [].fill([]) 来填充数组。它只会创建一个空数组对象,并将其用于初始化实际数组。这就是为什么以下代码片段会表现出应该表现的行为的原因 :)

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

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

0

这是我的解决方案:

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

let result = statuses.map(status => tableData.filter(tableDataItem => tableDataItem.Status == status));
console.log(result);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接