如何将元素插入到javascript中二维数组的特定索引中?
How to insert elements into specific index in a 2D array in javascript?
我有一个如下所示的对象
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
对象的每个项目都位于二维数组的某个索引中。因此,包含 Status
和 Reachable
的项目应该位于索引 0,包含 Status
和 Busy
的项目应该位于索引 1,依此类推。
所以最终的输出应该是这样的
[
[
{
"Location":"Delhi",
"Status":"Reachable"
}
],
[
{
"Location":"Tokyo",
"Status":"Busy"
}
],
[
{
"Location":"London",
"Status":"Unknown"
},
{
"Location":"Berlin",
"Status":"Unknown"
}
]
]
但是我在 运行 上面的代码中得到了错误的输出,即使我的目标是正确的索引。我的方法有什么问题?
使用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);
解决你的问题的简单方法是改变你的方式来设置 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)
另一种声明方式的解决方案:
首先使用 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; }
正如其他人所解释的那样,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([])
来填充数组。它只会创建一个空的 Array 对象并用它来初始化实际的数组。这就是为什么下面的代码片段表现得像它应该表现的那样:)
const statusOrderInfo = Array(3).fill([]);
statusOrderInfo[0].push(10);
console.log(statusOrderInfo);
/* Results:
[
[ 10 ],
[ 10 ],
[ 10 ]
]
*/
这是我的解决方案:
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);
我有一个如下所示的对象
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
对象的每个项目都位于二维数组的某个索引中。因此,包含 Status
和 Reachable
的项目应该位于索引 0,包含 Status
和 Busy
的项目应该位于索引 1,依此类推。
所以最终的输出应该是这样的
[
[
{
"Location":"Delhi",
"Status":"Reachable"
}
],
[
{
"Location":"Tokyo",
"Status":"Busy"
}
],
[
{
"Location":"London",
"Status":"Unknown"
},
{
"Location":"Berlin",
"Status":"Unknown"
}
]
]
但是我在 运行 上面的代码中得到了错误的输出,即使我的目标是正确的索引。我的方法有什么问题?
使用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);
解决你的问题的简单方法是改变你的方式来设置 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)
另一种声明方式的解决方案:
首先使用 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; }
正如其他人所解释的那样,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([])
来填充数组。它只会创建一个空的 Array 对象并用它来初始化实际的数组。这就是为什么下面的代码片段表现得像它应该表现的那样:)
const statusOrderInfo = Array(3).fill([]);
statusOrderInfo[0].push(10);
console.log(statusOrderInfo);
/* Results:
[
[ 10 ],
[ 10 ],
[ 10 ]
]
*/
这是我的解决方案:
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);