简体   繁体   English

使用嵌套对象和 arrays 时处理错误的正确方法

[英]Proper way of handling errors when working with nested objects and arrays

My data structure (condensed)我的数据结构(精简)

const data = {
  "cars": [
    {
      "name": "toyota",
      "sedan": {
        "2d": [
          {
            "name": "corolla",
            "year": 2020
          },
          {
            "name": "supra",
            "year": 1986
          }
        ]
      }
    }
  ]
};

To find the object by name, I would do:要按名称查找 object,我会这样做:

const twoDcars = data.cars.reduce(car => car.sedan);
const match = twoDcars.sedan['2d'].filter(car => car.name === "corolla");
console.log(match); //[ { name: 'corolla', year: 2020 } ]

With conditional check:有条件检查:

const twoDcars = data.cars && data.cars.reduce(car => car.sedan);
const match = twoDcars && twoDcars.sedan && twoDcars.sedan['2d'] && twoDcars.sedan['2d'].filter(car => car && car.name === "corolla");
console.log(match);  //[ { name: 'corolla', year: 2020 } ]

With try/catch:使用尝试/捕获:

let match;
try {
  match = data.cars.reduce(car => car.sedan).sedan['2d'].filter(car => car.name === "corolla");
} catch {}
console.log(match); //[ { name: 'corolla', year: 2020 } ]

My question is, what is the preferred/industry-standard of doing this.我的问题是,这样做的首选/行业标准是什么。

  • A && AB && ABC && ABC.D A && AB && ABC && ABC.D
  • try {ABC.D} catch{}试试 {ABC.D} 捕捉{}
  • Some other approach?其他一些方法?

My requirement is pretty simple.我的要求很简单。

  • Find the match if possible如果可能,找到匹配项
  • App shouldn't break on any conditions.应用程序不应在任何情况下中断。

What am I trying to do is avoid hundreds of && or `try{}catch{}`` everywhere in my code.我想要做的是避免在我的代码中到处出现数百个&&或 `try{}catch{}``。 I can create utility methods whenever possible but with the complex/nested data that I'm dealing with, it is often impossible.我可以尽可能创建实用程序方法,但是对于我正在处理的复杂/嵌套数据,这通常是不可能的。

If possible, I would probably do some massaging of the raw data to get it in a form where you can filter down at the top level and ensure you're not dealing with all the possible nulls everywhere in you code.如果可能的话,我可能会对原始数据进行一些处理,以使您可以在顶层过滤并确保您不会在代码中处理所有可能的空值。 I'd also get rid of the check on cars by ensuring there's always an empty list of cars.我还会通过确保始终有一个空的汽车清单来摆脱对cars的检查。 That way, filter and the rest will just work.这样,过滤器和 rest 就可以正常工作。

I would probably shoot to flatten the car objects into individual cars with all the props;我可能会用所有道具将汽车物体压平成单独的汽车; like so:像这样:

const data = {
  "cars": [
    {
      "year": 2020,
      "make": "toyota",
      "model": "corolla",
      "type": "sedan",
      "doors" : 2
    },
    {
      "year": 1986,
      "make": "toyota",
      "model": "supra",
      "type": "sedan",
      "doors" : 2
    }
  ]
};

I wouldn't use multiple chained filters for this I'm just showing how much easier it would be to filter more directly and get all sedans, two-door sedans, etc. simplifying your code and life:)我不会为此使用多个链式过滤器,我只是展示更直接地过滤并获得所有轿车、两门轿车等会变得多么容易。简化您的代码和生活:)

let results = data
  .cars
  .filter(car => car.type === 'sedan')     // all sedans
  .filter(car => car.doors === 2)          // two-door sedans
  .filter(car => car.model === 'corolla'); // two-door corollas

Of course, once you massage it, you can reorder the filters to be more direct;当然,一旦你按摩它,你可以重新排列过滤器更直接; like so (assuming you know a corolla is a sedan and you want only two-door models):像这样(假设您知道卡罗拉是轿车并且您只想要两门车型):

let results = data
  .cars
  .filter(car => car.model === 'corolla' && car.doors === 2);

Whether to use try/catch or to add in the guarding conditions, is a matter of opinion, although I have seen more often the guarded expressions.是使用try/catch还是添加保护条件,这是一个见仁见智的问题,尽管我经常看到受保护的表达式。

But there is no doubt that we're all going to be fans of the conditional chaining feature (also: mdn ), currently in stage 3.但毫无疑问,我们都将成为条件链接功能的粉丝(也: mdn ),目前处于第 3 阶段。

Then your code would look like:然后您的代码将如下所示:

const match = data.cars?.find(car => car.sedan)
              ?.sedan?.['2d']?.filter(car => car?.name === "corolla");

If searches in a nested object are frequent, then you could consider to flatten the structure into an array of non-nested objects.如果嵌套 object 中的搜索频繁,则可以考虑将结构展平为非嵌套对象数组。

To avoid a scan of the whole array, you could sort that array by one of its object-properties, allowing for a binary search.为避免扫描整个数组,您可以按其对象属性之一对该数组进行排序,从而允许进行二分搜索。 You can even add some Map objects as separate ways to access the same data, but by key.您甚至可以添加一些Map对象作为单独的方式来访问相同的数据,但通过键。 This obviously brings you back to more nesting, but it would be an additional structure (not replacing the array) for drilling down into your data faster than by filtering the whole lot.这显然会让您回到更多的嵌套,但这将是一个额外的结构(而不是替换数组),用于比过滤整个数据更快地深入到您的数据中。 Such a Map would hold per key an array of matching objects (no copies, but the same object references as in the main array).这样的 Map 将为每个键保存一个匹配对象的数组(没有副本,但与主数组中的 object 引用相同)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM