Почему lodash конвертирует мой массив в объект? - PullRequest
0 голосов
/ 21 ноября 2018

Я новичок в lodash и создал функцию, которая удаляет ключ из объекта, где значение равно нулю или пусто.Но когда я передаю свой объект, который содержит некоторую часть в виде массива, он удаляет массив и преобразует его в объект.

Ниже приведен мой код, который я попробовал:

     _.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который я предоставляю, чтобы опустить пустое и нулевое значение, поэтому он должен удалить все свойства из объекта «smallMap» как серии, выровнять пустой объект и должен также удалить высоту.

С другой стороны, он долженудалить "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%"
    }
  }
}

iЯ не могу найти, где проблема, любая помощь приветствуется.

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

две основные проблемы, одна из которых была упомянута @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();
}

Надеюсь, это поможет вам, не проверено должным образом, да просто краткое описание.

0 голосов
/ 25 января 2019

Если ваш код использует

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...
      })
  }
0 голосов
/ 21 ноября 2018

Вы выдаете в своей функции removeFalsies, где вы не учитываете должным образом для массивов.Помните, что массивы также являются объектами, и ваш чек на if (v && typeof v === 'object') недостаточен.

Что происходит, когда вы делаете:

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

Где, когда вы передаете массив в этом _.transform, k равен 0, и вы в конечном итоге создаете объект с key 0, какое значение будет тогда _.removeFalsies(v);

Просто поставьте точку останова или debugger в этом if, и вы легко сможете увидеть проблему.

Также обратите внимание, что в lodash уже есть множество методов для проверки таких объектов, как _.isObject, а также массивов _.isArray ... _.isString & _.isEmpty и т. Д.

...