【问题标题】:How to map over an array and use index such that empty values are eliminated?如何映射数组并使用索引以消除空值?
【发布时间】:2020-06-24 16:46:25
【问题描述】:

我有两个数组 keyValsrows 定义如下:

    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"
  }
]

【问题讨论】:

标签: javascript node.js arrays dictionary node-modules


【解决方案1】:
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;
}

【讨论】:

    【解决方案2】:

    您可以使用特殊的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,如果您有兴趣。

    【讨论】:

      【解决方案3】:
      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;
      }
      

      【讨论】:

      • 有没有办法可以更新function dArray(rows, keyVals) 而不是创建另一个函数?
      【解决方案4】:

      在返回响应之前,使用mapObject.entries 过滤对象中的空值。

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

      【讨论】:

        【解决方案5】:

        这是通过过滤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"
            }
          ];
        }

        【讨论】:

          猜你喜欢
          • 2021-06-22
          • 1970-01-01
          • 2018-12-30
          • 1970-01-01
          • 1970-01-01
          • 2017-11-06
          • 2011-01-12
          • 1970-01-01
          • 2021-12-28
          相关资源
          最近更新 更多