为什么lodash将我的数组转换为对象?

时间:2018-11-21 07:31:27

标签: javascript lodash

我对lodash并不陌生,并创建了一个函数,该函数从值为null或空白的对象中删除键。  但是,当我传递包含一部分作为数组的对象时,它将删除数组并将其转换为对象。

下面是我尝试的代码:

     _.mixin({ 'removeFalsies': this.removeFalsies });
        _.mixin({
                removeEmptyObjects: this.removeEmptyObjects
          });

         removeFalsies (obj) {
    return _.transform(obj, function (o, v, k) {

      if (v && typeof v === 'object') {

        if (v !== '') {
          o[k] = _.removeFalsies(v);
        }

      } else if (v === false) {
        o[k] = v;
      } else if (v) {
        o[k] = v;
      }
    });
  }
  removeEmptyObjects (obj) {
    return _(obj)
      .pickBy(_.isObject)
      .mapValues(_.removeEmptyObjects)
      .omitBy(_.isEmpty)
      .assign(_.omitBy(obj, _.isObject))
      .value();
  }

下面是我提供的JSON,可省略空白和null值,因此它应将“ smallMap”对象中的所有属性作为系列删除,align为空白对象,并且还应删除高度。

另一方面,它应该删除规则中的“ mid”以及子数组中的series1。

var finalProp = {
  "smallMap": {
    "series": {},
    "align": {},
    "height": ""
  },
  "series": [
    {
      "heatRules": [
        {
          "min": "#555",
          "mid": null
        }
      ],
      "mapPolygons": {
        "tooltipText": "{name}",
        "togglable": true
      },
      "id": "value"
    }
  ],
  "children": [
    {
      "type": "HeatLegend",
      "width": "100%",
      "series1": null
    }
  ]
}
_.removeEmptyObjects(_.removeFalsies(finalProp));

它正在按预期方式删除所有内容,但只有1个问题正在将数组转换为对象。

它在下面提供了错误的输出,而不是序列:{0:{}},它应该提供序列:[{}],而不是子项:{0:{}},它应该提供[{}]。

{
      "series": {
        "0": {
          "heatRules": {
            "0": {
              "min": "#555"
            }
      },
      "mapPolygons": {
        "tooltipText": "{name}",
        "togglable": true
      },
      "id": "value"
    }
  },
  "children": {
    "0": {
      "type": "HeatLegend",
      "width": "100%"
    }
  }
}

我找不到任何帮助的问题所在。

3 个答案:

答案 0 :(得分:1)

问题出在函数removeFalsies中,在该函数中您无法正确考虑数组。请记住,数组也是对象,对if (v && typeof v === 'object')的检查还不够。

发生的事情是您要做的:

if (v && typeof v === 'object') {
  if (v !== '') {
    o[k] = _.removeFalsies(v);
  }
}

当您在其中传递_.transform的数组时,k0,最后创建的对象是key 0,其值就是{{1} }

只需在该_.removeFalsies(v);中插入一个断点或debugger,您就可以轻松地看到问题所在。

还请注意,lodash已经拥有许多方法来检查诸如if以及数组_.isObject ... _.isArray_.isString等对象。

答案 1 :(得分:1)

主要存在两个问题,@ Akrion提到了其中一个问题,您可以执行以下操作:

removeFalsies (obj) {

return _.transform(obj, function (o, v, k, l) {

    // here you have to check for array also as typeof will return object for array also
  if (v && _.isObject(v) && !_.isArray(v)) {

    if (v !== '' && !_.omitBy(v, _.isObject)) {
      o[k] = removeFalsies(v);
    }

  } else if(_.isArray(v)) {
  if(!o.hasOwnProperty(k)) o[k] = [];

  //And if it is array loop through it

  _.forEach(v, function(v1, k1) {
     o[k].push(removeFalsies(v1));
  });

  } else if (v === false) {
    o[k] = v;
  } else if (v) {
    o[k] = v;
  }
});
}

在调用函数时,只需尝试删除mapValues即可创建对象并在对象中转换数组,因为您的键0已转换为键

removeEmptyObjects =function (obj) {
      return _(obj).pickBy(_.isObject).omitBy(_.isEmpty).assign(_.omitBy(obj, _.isObject)).value();
}

希望这对您有所帮助,只是简短说明而未正确测试。

答案 2 :(得分:0)

如果您的代码使用

typeof v === 'object'

它将为true返回arrays

要检查array,请使用

Array.isArray(t)

array处理为object并遍历键会导致问题。

要递归但不能处理数组的样本函数

function removeFalsies(obj) {
  return _.transform(obj, function(o, v, k, l) {
      if (Array.isArray(obj) {
          for (let arrItem of obj) {
            removeFalsies(arrItem);
          }
          return
        }
        // else not array...
      })
  }