【问题标题】:Issues with Item in Object being 'undefined'对象中的项目“未定义”的问题
【发布时间】:2020-03-18 18:05:38
【问题描述】:

我正在尝试对一组对象进行排序和分组。但是,我遇到了一个问题,即调用键名“驱动程序”返回“未定义”。

代码如下:

let hos = [
    {
        "Driver": "test-000000",
        "Date": "3/15/2020",
        "Status": "Off-Duty",
        "Time": "12:00 AM",
        "": "",
        "__1": "",
        "__2": ""
    },
    {
        "Driver": "test-000000",
        "Date": "3/16/2020",
        "Status": "Off-Duty",
        "Time": "12:00 AM",
        "": "",
        "__1": "",
        "__2": ""
    }
];

let hosByDriver = [];

hos.forEach((item, index) => {
// If the current item.Driver string match the previous or next '.Driver' push it to an array inside hosByDriver[targetedDriver] else push it by itself
    if (item.Driver == hos[index + 1].Driver || item.Driver == hos[index - 1].Driver) {
        hosByDriver[item.Driver].push(item);
    } else {
        hosByDriver[item.Driver].push(item);
    }
});

【问题讨论】:

  • hos[index + 1].Driverhos[index - 1].Driver 可能会尝试访问 hos 数组上的 undefined 值,尤其是在 index === 0index === hos.length - 1 时,这将在迭代时发生两次在一个数组上,每个条件一次。
  • hosByDriver 是数组,而不是对象。我认为错误在这里:hosByDriver[item.Driver]
  • 您的代码没有任何意义。你在 if & else 语句中做同样的事情。
  • 感谢大家的回复!我发现您可以通过字符串而不是索引值调用数组索引。因此,我为什么要这样做。不幸的是,我失去了使用物体推动的能力。不知道为什么我会遇到这个问题,似乎是基本的 js .. @palash,本质上,如果在当前“项目”之前或之后没有其他条目,它只会将其推送到数组中。 IE。司机当天下班,状态只会是下班,没有其他条目
  • 你是对的。它确实做同样的事情。我得重写这个......

标签: javascript arrays json sorting grouping


【解决方案1】:

在第一次迭代中(索引为 0)您的代码如下所示

hos.map((item, index) => {
    console.log(index);
    // neither hos[1] nor hos[-1] do exist -> undefined
    if (item.Driver == hos[0+1] || item.Driver == hos[0-1].Driver) {
        hosByDriver[item.Driver].push(item);
    } else {
        hosByDriver[item.Driver].push(item);
    }
});

所以它在第一轮就崩溃了。 hos[0-1].Driver 计算结果为 undefined.Driver。您可以使用 && 解决此问题。

注意:array[-1] 不是无效语法

hos[index - 1] && hos[index - 1].Driver

另外,item.Driver 是一个字符串。数组通常按数字索引。我认为您的意思是使用 Object 代替:

let hosByDriver = {};

hos.forEach((item, index) => {
  console.log(index);
  if (hos[index - 1] && (item.Driver === hos[index + 1] ||  item.Driver === hos[index - 1].Driver)) {
    //hosByDriver[item.Driver] = [];
    //hosByDriver[item.Driver].push(item);
  } else {
    hosByDriver[item.Driver] = [];
    hosByDriver[item.Driver].push(item);
  }
});

我还将 .map 更改为 .forEach,因为您没有返回一个新数组,该数组除外。如果您只想迭代,则 forEach 是等价的。

我只是在这里猜测您想要实现的目标,如果您提供更多详细信息,我可以提供更好的解决方案。看看这个代码框:

https://codesandbox.io/s/stackoverflow-3h2n9

我认为您需要阅读一些关于 JavaScript 的基础知识(如数据类型、循环等)。也就是说,继续学习! :)

更新: 如果我理解正确,您不会在 hosByDriver 中对存储在 hos 中的同名驱动程序进行分组。用例是访问像hosByDriver['test-000000'] 这样的驱动程序的所有项目,并避免一遍又一遍地迭代整个数组,这是有道理的。

您可以通过以下操作轻松实现此目的

let hosByDriver = {};

hos.forEach(item => {

  // if item or item.Driver could be not what you expect you could check with 
  // item && item.Driver && typeof item.Driver === "string" 
  // in your if statement
  if(!hosByDriver[item.Driver]){ 
  // set hosByDriver[item.Driver] to empty array if it is undefined (more precisly: if its [falsy][1], meaning either 0, "", undefined, null ,NaN or false
    hosByDriver[item.Driver] = []
  }
  // append item to array at hosByDriver[item.Driver]
  // either empty or holding previous items
  hosByDriver[item.Driver].push(item);
});

信息:

在 JavaScript 中,数组实际上只是对象(键/值对)。如果您想了解更多相关信息,可以观看JavaScript: Understanding the Weird Parts。数组是一种特殊情况,您访问一个从零开始的数字的值,即使我认为您无论如何都可以放置字符串 - 因为 JavaScript 非常宽容 - 我不建议这样做。当它变得更复杂时,您将很难进行调试。

也不建议使用 ==,而是使用 === 来防止 JS-Engine 尝试进行类型转换。例如。 0 == "" 产生 true。这也会给你带来很多麻烦。

【讨论】:

  • 你好,谢谢你的回复!在我当前的司机列表和他们的职责状态中,过去一周大约有 2000 个条目,所以我可以看到演示代码失败的原因。此外,我意识到我错过了最初 if 语句中的“.Driver”部分。所以,hos[ index + 1 ].Driver 。在您的解决方案中,您注意到 `hosByDriver[item.Driver] = []; hosByDriver[item.Driver].push(item);` 本质上,我编写代码的方式就像一个构造函数,即。如果目标驱动程序键不是数组,则为 .push(item) 创建一个数组
  • 嘿,你是对的。该代码将仅存储最后一个驱动程序。请参阅我的答案中的更新部分。我还更新了代码框。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 2017-12-24
  • 2012-08-18
  • 2017-09-24
  • 2017-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多