未定义属性为第二个值插入jsons数组

时间:2017-05-25 09:00:58

标签: javascript json

我在javascript中执行以下代码:

 var res = [{}];
    for (var idx = 0; idx < json.length; idx++) {
        // if the environment is already entered in the result
        if (res[idx].env) {
            sails.log.debug('Environment is in result');
            // if the current inspected value has been deployed later than the stored one
            if (res[idx].updatedAt < json[idx].updatedAt) {
                sails.log.debug('Updating the value in the result');
                //res[json[idx].lifeCycle] = JSON.parse('{"'+json[idx].version+'":"'+json[idx].updatedAt+'"}');
                res.env = json[idx].lifeCycle;
                res.ver = json[idx].version;
                res.updatedAt = json[idx].updatedAt;
            }
        } else {
            // it is the first time we are adding to the result the component version (for the given environment)
            if (json[idx].lifeCycle) {
                //add the value in result
                res[idx].env = json[idx].lifeCycle || '';
                res[idx].ver = json[idx].version || '';
                res[idx].updatedAt = json[idx].updatedAt || '';
            }
            else {
                sails.log.debug('Lifecycle is null or empty');
            }
        }
    }
    return res;

此代码接收包含多个值的多个元素的JSON。完成检查后,它会显示在底线

if (json[idx].lifeCycle) {
                //add the value in result
                res[idx].env = json[idx].lifeCycle || '';
                res[idx].ver = json[idx].version || '';
                res[idx].updatedAt = json[idx].updatedAt || '';
            }

在这里,IDX等于1(第二次绕过for循环)。

当我尝试将第二个值插入“res”时,我收到错误:

TypeError: Cannot read property 'env' of undefined

在第一次通过for循环后,就好像res不再存在一样。

任何人都可以帮助我,让我知道为什么会这样吗?

非常感谢!

1 个答案:

答案 0 :(得分:2)

好吧,如果你看一下你的res数组,它只有一个元素,它是一个空对象。 所以它意味着:

res[0] // -> {}

res[1] // -> undefined

简单的解决方案(最少改变代码的解决方案)

您只需在尝试访问数组中的res[idx]元素时创建新对象。

您的代码看起来像这样

if (json[idx].lifeCycle) {
  res[idx] = res[idx] || {}; // if the index `idx` is not set, just init it to an empty object
  res[idx].env = json[idx].lifeCycle || '';
  res[idx].ver = json[idx].version || '';
  res[idx].updatedAt = json[idx].updatedAt || '';
}

稍微好一点的解决方案

或者您甚至可以简化一些代码并在每个循环中创建一个新对象并将其推送到res数组中。如果这样做,您还必须将res数组初始化为空数组var res = []

if (json[idx].lifeCycle) {
  res.push({
    env: json[idx].lifeCycle || '',
    ver: json[idx].version || '',
    updatedAt: json[idx].updatedAt || ''
  })
}

这样,如果你在数组中有元素,你就不需要处理特殊情况,你只需要处理每一个循环

最佳解决方案(IMO):功能编程FTW

不确定您是否了解Array.prototype.map之类的数组函数。这是一个函数,允许您在数组的每个元素上映射函数,将其转换为转换元素。它创建了一个由转换元素组成的新数组。

以下是使用精彩map方法的代码:

var res = json
    .map(function (element) {
      return {
        env: json[idx].lifeCycle || '',
        ver: json[idx].version || '',
        updatedAt: json[idx].updatedAt || ''
      }
    });

如果我在res中没有问题,那么您将获得与您编码产生的值相同的值。

我删除了我认为永远不会if (res[idx].env)的第一个条件true,因为res[idx]将是undefined或空对象(但我可能错了) )。

无论如何,如果您觉得此解决方案很酷,请务必查看MDN上的mapfilterreduce上的文档:) https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map