如何映射数组并使用索引以消除空值?
How to map over an array and use index such that empty values are eliminated?
我有两个数组 keyVals
和 rows
定义如下:
keyVals =
[
"Status",
"ErrorHeading",
"ErrorDetail"
]
rows =
[
{
"Hostname": "ABC",
"name": "Check1",
"Status": "PASS",
"ErrorHeading": "",
"ErrorDetail": ""
},
{
"Hostname": "ABC",
"name": "Check2",
"Status": "PASS",
"ErrorHeading": "",
"ErrorDetail": ""
},
{
"Hostname": "ABC",
"name": "Check3",
"Status": "FAIL",
"ErrorHeading": "Heading3",
"ErrorDetail": "ErrorDetails3"
}
]
我写了下面的代码来生成一个Res
:
function dArray(rows, keyVals) {
const response = Object.values(rows.reduce((res, {Hostname, name, ...o}) => {
res[Hostname] = res[Hostname] || {Hostname};
keyVals.forEach(kv => res[Hostname][name + kv] = o[kv]);
return res;
}, {}));
return response;
}
const Res = dArray(rows, keyVals);
Res
值如下所示:
Res =
[
{
"Hostname": "ABC",
"Check1kStatus": "PASS",
"Check1ErrorHeading": "",
"Check1ErrorDetail": "",
"Check2Status": "PASS",
"Check2ErrorHeading": "",
"Check2ErrorDetail": "",
"Check3Status": "FAIL",
"Check3ErrorHeading": "Heading3",
"Check3ErrorDetail": "ErrorDetails3"
}
]
我想修改 function dArray(rows, keyVals)
以便 Res
排除所有空值,如下所示:
Res =
[
{
"Hostname": "ABC",
"Check1kStatus": "PASS",
"Check2Status": "PASS",
"Check3Status": "FAIL",
"Check3ErrorHeading": "Heading3",
"Check3ErrorDetail": "ErrorDetails3"
}
]
function dArray(rows, keyVals) {
const response = Object.values(rows.reduce((res, {Hostname, name}) => {
res[Hostname] = res[Hostname] || {Hostname};
keyVals.forEach(kv => res[Hostname][name + kv] = o[kv]);
return res;
}, {}));
let keys=Object.keys(response[0]);
for(let i=0,l=keys.length;i<l;i++){
if(!response[0][keys[i]]){
delete response[0][keys[i]];
}
}
return response;
}
您可以使用特殊的 filterObject
函数来完成。
const keyVals = ["Status", "ErrorHeading", "ErrorDetail"]
const rows = [
{ "Hostname": "ABC", "name": "Check1", "Status": "PASS", "ErrorHeading": "", "ErrorDetail": "" },
{ "Hostname": "ABC", "name": "Check2", "Status": "PASS", "ErrorHeading": "", "ErrorDetail": "" },
{ "Hostname": "ABC", "name": "Check3", "Status": "FAIL", "ErrorHeading": "Heading3", "ErrorDetail": "ErrorDetails3" },
]
const filterObject = (fn, x) => {
const y = {}
for (const k in x) {
const ok = fn(x[k])
if (ok) { y[k] = x[k] }
}
return y
}
function dArray(rows, keyVals) {
const response = Object.values(rows.reduce((res, {Hostname, name, ...o}) => {
res[Hostname] = res[Hostname] || {Hostname};
keyVals.forEach(kv => res[Hostname][name + kv] = o[kv]);
return res;
}, {}));
return response.map(obj => filterObject(x => x !== '', obj))
}
const Res = dArray(rows, keyVals);
console.log(Res)
filterObject
改编自我的函数式编程库 rubico 中的多态过滤器。过滤器文档 here,如果您有兴趣。
function dArray(rows, keyVals) {
const response = Object.values(rows.reduce((res, {Hostname, name, ...o}) => {
res[Hostname] = res[Hostname] || {Hostname};
keyVals.forEach(kv => (o[kv] && (res[Hostname][name + kv] = o[kv])));
return res;
}, {}));
return response;
}
在返回response之前,使用map
和Object.entries
过滤object中的空值。
function dArray(rows, keyVals) {
const response = Object.values(
rows.reduce((res, { Hostname, name, ...o }) => {
res[Hostname] = res[Hostname] || { Hostname };
keyVals.forEach((kv) => (res[Hostname][name + kv] = o[kv]));
return res;
}, {})
);
return response.map((obj) =>
Object.fromEntries(Object.entries(obj).filter(([, val]) => val))
);
}
keyVals = ["Status", "ErrorHeading", "ErrorDetail"];
rows = [
{
Hostname: "ABC",
name: "Check1",
Status: "PASS",
ErrorHeading: "",
ErrorDetail: "",
},
{
Hostname: "ABC",
name: "Check2",
Status: "PASS",
ErrorHeading: "",
ErrorDetail: "",
},
{
Hostname: "ABC",
name: "Check3",
Status: "FAIL",
ErrorHeading: "Heading3",
ErrorDetail: "ErrorDetails3",
},
];
console.log(dArray(rows, keyVals));
这是通过过滤 Object.values()
调用的输出来实现的。
const
keyVals = [ "Status", "ErrorHeading", "ErrorDetail" ],
rows = getRows();
function dArray(rows, keyVals) {
const reducedValues = Object.values(
rows.reduce( (res, { Hostname, name, ...o }) => {
res[Hostname] = res[Hostname] || { Hostname };
keyVals.forEach(kv => res[Hostname][name + kv] = o[kv]);
return res;
}, {})
),
response = [
Object.fromEntries(
Object.entries(reducedValues[0]).filter(en=>en[1])
)
];
return response;
}
const Res = dArray(rows, keyVals);
console.log(Res);
function getRows(){
return [{
"Hostname": "ABC",
"name": "Check1",
"Status": "PASS",
"ErrorHeading": "",
"ErrorDetail": ""
},
{
"Hostname": "ABC",
"name": "Check2",
"Status": "PASS",
"ErrorHeading": "",
"ErrorDetail": ""
},
{
"Hostname": "ABC",
"name": "Check3",
"Status": "FAIL",
"ErrorHeading": "Heading3",
"ErrorDetail": "ErrorDetails3"
}
];
}
我有两个数组 keyVals
和 rows
定义如下:
keyVals =
[
"Status",
"ErrorHeading",
"ErrorDetail"
]
rows =
[
{
"Hostname": "ABC",
"name": "Check1",
"Status": "PASS",
"ErrorHeading": "",
"ErrorDetail": ""
},
{
"Hostname": "ABC",
"name": "Check2",
"Status": "PASS",
"ErrorHeading": "",
"ErrorDetail": ""
},
{
"Hostname": "ABC",
"name": "Check3",
"Status": "FAIL",
"ErrorHeading": "Heading3",
"ErrorDetail": "ErrorDetails3"
}
]
我写了下面的代码来生成一个Res
:
function dArray(rows, keyVals) {
const response = Object.values(rows.reduce((res, {Hostname, name, ...o}) => {
res[Hostname] = res[Hostname] || {Hostname};
keyVals.forEach(kv => res[Hostname][name + kv] = o[kv]);
return res;
}, {}));
return response;
}
const Res = dArray(rows, keyVals);
Res
值如下所示:
Res =
[
{
"Hostname": "ABC",
"Check1kStatus": "PASS",
"Check1ErrorHeading": "",
"Check1ErrorDetail": "",
"Check2Status": "PASS",
"Check2ErrorHeading": "",
"Check2ErrorDetail": "",
"Check3Status": "FAIL",
"Check3ErrorHeading": "Heading3",
"Check3ErrorDetail": "ErrorDetails3"
}
]
我想修改 function dArray(rows, keyVals)
以便 Res
排除所有空值,如下所示:
Res =
[
{
"Hostname": "ABC",
"Check1kStatus": "PASS",
"Check2Status": "PASS",
"Check3Status": "FAIL",
"Check3ErrorHeading": "Heading3",
"Check3ErrorDetail": "ErrorDetails3"
}
]
function dArray(rows, keyVals) {
const response = Object.values(rows.reduce((res, {Hostname, name}) => {
res[Hostname] = res[Hostname] || {Hostname};
keyVals.forEach(kv => res[Hostname][name + kv] = o[kv]);
return res;
}, {}));
let keys=Object.keys(response[0]);
for(let i=0,l=keys.length;i<l;i++){
if(!response[0][keys[i]]){
delete response[0][keys[i]];
}
}
return response;
}
您可以使用特殊的 filterObject
函数来完成。
const keyVals = ["Status", "ErrorHeading", "ErrorDetail"]
const rows = [
{ "Hostname": "ABC", "name": "Check1", "Status": "PASS", "ErrorHeading": "", "ErrorDetail": "" },
{ "Hostname": "ABC", "name": "Check2", "Status": "PASS", "ErrorHeading": "", "ErrorDetail": "" },
{ "Hostname": "ABC", "name": "Check3", "Status": "FAIL", "ErrorHeading": "Heading3", "ErrorDetail": "ErrorDetails3" },
]
const filterObject = (fn, x) => {
const y = {}
for (const k in x) {
const ok = fn(x[k])
if (ok) { y[k] = x[k] }
}
return y
}
function dArray(rows, keyVals) {
const response = Object.values(rows.reduce((res, {Hostname, name, ...o}) => {
res[Hostname] = res[Hostname] || {Hostname};
keyVals.forEach(kv => res[Hostname][name + kv] = o[kv]);
return res;
}, {}));
return response.map(obj => filterObject(x => x !== '', obj))
}
const Res = dArray(rows, keyVals);
console.log(Res)
filterObject
改编自我的函数式编程库 rubico 中的多态过滤器。过滤器文档 here,如果您有兴趣。
function dArray(rows, keyVals) {
const response = Object.values(rows.reduce((res, {Hostname, name, ...o}) => {
res[Hostname] = res[Hostname] || {Hostname};
keyVals.forEach(kv => (o[kv] && (res[Hostname][name + kv] = o[kv])));
return res;
}, {}));
return response;
}
在返回response之前,使用map
和Object.entries
过滤object中的空值。
function dArray(rows, keyVals) {
const response = Object.values(
rows.reduce((res, { Hostname, name, ...o }) => {
res[Hostname] = res[Hostname] || { Hostname };
keyVals.forEach((kv) => (res[Hostname][name + kv] = o[kv]));
return res;
}, {})
);
return response.map((obj) =>
Object.fromEntries(Object.entries(obj).filter(([, val]) => val))
);
}
keyVals = ["Status", "ErrorHeading", "ErrorDetail"];
rows = [
{
Hostname: "ABC",
name: "Check1",
Status: "PASS",
ErrorHeading: "",
ErrorDetail: "",
},
{
Hostname: "ABC",
name: "Check2",
Status: "PASS",
ErrorHeading: "",
ErrorDetail: "",
},
{
Hostname: "ABC",
name: "Check3",
Status: "FAIL",
ErrorHeading: "Heading3",
ErrorDetail: "ErrorDetails3",
},
];
console.log(dArray(rows, keyVals));
这是通过过滤 Object.values()
调用的输出来实现的。
const
keyVals = [ "Status", "ErrorHeading", "ErrorDetail" ],
rows = getRows();
function dArray(rows, keyVals) {
const reducedValues = Object.values(
rows.reduce( (res, { Hostname, name, ...o }) => {
res[Hostname] = res[Hostname] || { Hostname };
keyVals.forEach(kv => res[Hostname][name + kv] = o[kv]);
return res;
}, {})
),
response = [
Object.fromEntries(
Object.entries(reducedValues[0]).filter(en=>en[1])
)
];
return response;
}
const Res = dArray(rows, keyVals);
console.log(Res);
function getRows(){
return [{
"Hostname": "ABC",
"name": "Check1",
"Status": "PASS",
"ErrorHeading": "",
"ErrorDetail": ""
},
{
"Hostname": "ABC",
"name": "Check2",
"Status": "PASS",
"ErrorHeading": "",
"ErrorDetail": ""
},
{
"Hostname": "ABC",
"name": "Check3",
"Status": "FAIL",
"ErrorHeading": "Heading3",
"ErrorDetail": "ErrorDetails3"
}
];
}