【问题标题】:Check if part of multidimensional array is null before assigning在分配之前检查多维数组的一部分是否为空
【发布时间】:2021-05-05 10:26:10
【问题描述】:

我有一个 HTML 预览页面,它显示来自 API 调用 (multidimensional array) 的数据。

我想将此数组数据显示为<table>。在此之前我需要检查一些参数以增强可读性,为此我使用函数setFeature()

问题:

多维数组并不总是有所有可用的选项字段。例如,在下面的预览中,您可以看到 selectA 中的 optiondnull。当 optiondnot null 时,它将包含多个子值,就像您在 selectB 中看到的那样。

尝试将databank[0]['selectA']['optiond']['suba'] 传递给函数setFeature() 时。将显示错误TypeError: databank[0].selectA.optiond is null"

我尝试过的:

// Checking the variable "suba" before passing to the function "setFeature()"
var suba = databank[0]['selectA']['optiond']['suba']; // added into variable for enhanced readability.
preview += (suba !== null) ? setFeature('D', suba) : '';

这工作没有错误(*)

var optiond = databank[0]['selectA']['optiond'];
if (optiond !== null) {
    setFeature('D', databank[0]['selectA']['optiond']['suba']) 
}

问题:

我正在寻找一种最短的方法在它为空时忽略该值,而不会造成编码行的过载。

(*) 使用这种方法(检查parent是否为空)会导致代码行超载,因为多维数组很大,我只需要15%的数组信息向客户展示。

代码 sn-p:

var databank = [{
  "selectA": {
    "optiona": "Some string information",
    "optionb": true,
    "optionc": false,
    "optiond": null,
    "optione": "Courant",
  },
  "selectB": {
    "optiona": "Some string information",
    "optionb": true,
    "optionc": true,
    "optiond": {
      "suba": 30.0,
      "subb": 10.0,
      "subc": 10.0,
      "subd": null
    },
    "optione": "Courant",
  }
}];

var preview;
preview += setFeature('A', databank[0]['selectA']['optiona']);
preview += setFeature('B', databank[0]['selectA']['optionb']);
preview += setFeature('C', databank[0]['selectA']['optionc']);
preview += setFeature('D', databank[0]['selectA']['optiond']['suba']);
preview += setFeature('E', databank[0]['selectA']['optione']);
$('#test').append(preview);

function setFeature(name, data) {
  if (data !== null && data !== undefined && data.toString().toLowerCase() !== 'onbekend') {
    console.log('PASSED: ' + name + ': ' + data + ', length: ' + data.length);
    if (typeof data === "boolean") {
      if (data === true) {
        return '<tr><th scope="row">' + name + '</th><td>Yes</td></tr>';
      } else {
        return '<tr><th scope="row">' + name + '</th><td>No</td></tr>';
      }
    } else {
      return '<tr><th scope="row">' + name + '</th><td>' + data + '</td></tr>';
    }
  } else {
    return '';
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table id="test"></table>

【问题讨论】:

  • 使用Optional chaining operator,你可以写成databank[0]['selectA']['optiond']?.suba。对于不存在的属性返回 undefined,因此需要相应地修改 data !== null 检查,否则 data.toLowerCase 将在 undefined 下失败。
  • 还缺少toLowerCase() () 来调用它
  • @CBroe 您的评论应该是一个答案。据我所知,您的评论是最短的方法。在我的函数 setFeature() 中添加了对等于 undefined 的变量的检查来处理您的代码。 @charlietfl 感谢您指出缺少的 ()
  • 请注意有限的支持和运营商的草案状态。

标签: javascript jquery arrays


【解决方案1】:

使用Optional chaining operator,你可以这样写

databank[0]['selectA']['optiond']?.suba

对于不存在的属性返回undefined,因此需要相应地修改data !== null 检查,否则data.toLowerCase() 将在下一次未定义时失败。

该运算符仅适用于访问属性的点符号,不适用于['suba']。但是,由于您在这里看起来不需要任何类型的动态解决方案(将使用foo[variable],不能以同样的方式替换为foo.variable),这应该不是问题。

【讨论】:

    【解决方案2】:

    不幸的是,无论哪种方式,它看起来都不漂亮,因为如果它在中途未定义,则无法嵌套到数组中。

    if (ArrayTest === undefined) return;
    if (ArrayTest["test"] === undefined) return;
    if (ArrayTest["test"]["test"] === undefined) return;
    

    不过,有一些方法可以让这看起来更好,

    Object = {
      tester:()=>{
        console.log("works");
      }
    };
    let type = "tester";
    if (typeof Object[type] === "function") {
      Object[type]();
    }

    你可以在你的通话中运行丑陋的 try-catch

        try{
           console.log(TestArray["test"]["test"].testvalue);
        }catch(e){
           console.log("no such variable");
        }

    【讨论】:

      【解决方案3】:

      var databank = [{
        "selectA": {
          "optiona": "Some string information",
          "optionb": true,
          "optionc": false,
          "optiond": null,
          "optione": "Courant",
        },
        "selectB": {
          "optiona": "Some string information",
          "optionb": true,
          "optionc": true,
          "optiond": {
            "suba": 30.0,
            "subb": 10.0,
            "subc": 10.0,
            "subd": null
          },
          "optione": "Courant",
        }
      }];
      
      const get = (o, ...path) => o!= null && path.length ? get(o[path.shift()],...path) : o;
      
      for(const select of ['selectA','selectB']) {
        let preview = setFeature('A', get(databank,0,select,'optiona'));
        preview += setFeature('B', get(databank,0,select,'optionb'));
        preview += setFeature('C', get(databank,0,select,'optionc'));
        preview += setFeature('D', get(databank,0,select,'optiond', 'suba'));
        preview += setFeature('E', get(databank,0,select,'optione'));
        $('#test').append(preview);
      }
      function setFeature(name, data) {
        if (data != null && data.toLowerCase != 'onbekend') {
          console.log('PASSED: ' + name + ': ' + data + ', length: ' + data.length);
          if (typeof data === "boolean") {
            if (data === true) {
              return '<tr><th scope="row">' + name + '</th><td>Yes</td></tr>';
            } else {
              return '<tr><th scope="row">' + name + '</th><td>No</td></tr>';
            }
          } else {
            return '<tr><th scope="row">' + name + '</th><td>' + data + '</td></tr>';
          }
        } else {
          return '';
        }
      }
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      
      <table id="test"></table>

      【讨论】:

        猜你喜欢
        • 2021-05-13
        • 1970-01-01
        • 1970-01-01
        • 2013-08-26
        • 1970-01-01
        • 2010-10-09
        • 2020-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多