Как удалить пустые экземпляры из массива при использовании рекурсивной чистой функции? - PullRequest
0 голосов
/ 12 февраля 2019

Для справки. Используя Postman (инструмент API REST), мы сравниваем XML с шаблоном, конвертируя XML в JSON, и сравниваем их как объекты Javascript.Сравнение может обрабатывать подстановочные знаки в значениях и будет возвращать новый объект JS (или JSON) только с различиями.Когда нет различий, я получаю пустой объект, который находится в правильном состоянии.В некоторых случаях возвращаются пустые значения или объекты, и мы удаляем их из объекта чистым шагом.

Так выглядит функция очистки :

Utils = {
  clean: function(object) {
    Object
        .entries(object)
        .forEach(([k, v]) => {
            if (v && typeof v === 'object') 
                Utils.clean(v);
            if (v && typeof v === 'object' && !Object.keys(v).length || v === null || v === undefined) 
                Array.isArray(object) ? object.splice(k, 1) :  delete object[k]; 
        });
    return object;
  }
}

Это работает нормально для большинства случаев, за исключением случаев, когда у нас есть массив с несколькими одинаковыми пустыми объектами из-за object.splice в сочетании с foreach , как указано здесь .

Обычно, Я хотел бы использовать функцию фильтра, использовать _.pickBy из lodash или итерировать в обратном направлении через массив, но из-за расположения функции clean я не могу понять, как это сделать.

МожетВы помогаете мне указать, что мне нужно сделать, чтобы правильно удалить несколько пустых элементов и объектов из массива.

Реальный тестовый случай:

var x = {"Document":{"CstmrDrctDbtInitn":{"GrpHdr":{},"PmtInf":{"DrctDbtTxInf":[{"PmtId":{}},{"PmtId":{}},{"PmtId":{}},{"PmtId":{}},{"PmtId":{}}]}}}};
console.log(JSON.stringify(Utils.clean(x)));
// returns {"Document":{"CstmrDrctDbtInitn":{"PmtInf":{"DrctDbtTxInf":[{},{}]}}}}
// desired result: {}

Другие тестовые случаи:

console.log(JSON.stringify(Utils.clean({"a": [null,null,"b","c",{},{},{},{}]})));
// returns {"a":[null,"c",{},{},{}]} 
// desired: {"a":["b", "c"]}

console.log(JSON.stringify(Utils.clean({"a": [null,null,"b","c",{"d": {}},{}]})));
// returns {"a":[null,"c",{},{}]} 
// desired: {"a":["b", "c"]}

console.log(JSON.stringify(Utils.clean({ "a" : [null,null,{"d": {}, "e": [null, {}]},{}]})));
// returns {"a":[null,{}]} 
// desired: {}

1 Ответ

0 голосов
/ 12 февраля 2019

Сделайте это, и вот рабочий пример: https://jsfiddle.net/3rno4L7d/

Использует объект (с дополнительными помощниками)

const Utils = {
  doDelete: function(val) {
    return !Boolean(val) ||
      Utils.isEmptyObj(val) ||
      Utils.isEmptyArray(val);
  },
  isEmptyArray: function(val) {
    return Array.isArray(val) && val.length === 0;
  },
  isEmptyObj: function(obj) {
    return Object.keys(obj).length === 0 &&
      obj.constructor === Object;
  },
  hasKeys: function(obj) {
    return Object.keys(obj).length > 0;
  },
  clean: function(object) {
    Object
      .keys(object)
      .forEach(key => {
        const val = object[key];

        // If dealing with an object, clean it.
        if (val && typeof val === 'object') {
            Utils.clean(val);
        }

        // If deleteable, delete and return
        if (Utils.doDelete(val)) {
          delete object[key];
          return object;
        }

        // If array, loop over entries
        if (Array.isArray(val)) {
          let i = val.length;

          // While lets us delete from the array without affecting the loop.
          while (i--) {
            let entry = val[i];
            // If deleteable, delete from the array
            if (Utils.doDelete(entry)) {
              val.splice(i, 1)
            } else if (Utils.hasKeys(entry)) {
              // If an object, clean it
              entry = Utils.clean(entry);
              // Check to see if cleaned object is deleteable
              if (Utils.doDelete(entry)) {
                val.splice(i, 1)
              }
            }
          }
          // Once done with the array, check if deleteable
          if (Utils.doDelete(val)) {
            delete object[key];
          }
        }
      });
    return object;
  }
}

Выход

console.log(JSON.stringify(Utils.clean({"a": [null,null,"b","c",{},{},{},{}]})));
// Returns {"a":["b","c"]}

console.log(JSON.stringify(Utils.clean({"a": [null,null,"b","c",{"d": {}},{}]})));
// Returns {"a":["b","c"]}

console.log(JSON.stringify(Utils.clean({ "a" : [null,null,{"d": {}, "e": [null, {}]},{}]})));
// Returns {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...