Удалить пустые и нулевые значения из вложенного объекта (ES6) - Очистить вложенные объекты - PullRequest
0 голосов
/ 17 сентября 2018

Я получил объект, который выглядит следующим образом:

{
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0,
        "k": null
    },
    "l": {
        "m": null
    },
    "n": {
        "o": 1,
        "p": "string (not empty)",
        "q": {}
    },
    "r": [],
    "l": "2000-01-01T01:01:00.000Z",
}

Благодаря приведенному здесь коду: https://stackoverflow.com/a/38364486/3912805 Теперь я могу удалить все null значения моего вложенного объекта.

Я использовал эту функцию до removeNull:

removeNull = (obj) => {
  Object.keys(obj).forEach(key =>
    (obj[key] && typeof obj[key] === 'object') && removeNull(obj[key]) ||
    (obj[key] === undefined || obj[key] === null) && delete obj[key]
  );
  return obj;
};

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

Окончательные результаты должны быть без k, l & m, q, r, l:

{
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0
    },
    "n": {
        "o": 1,
        "p": "string (not empty)"
    },
    "l": "2000-01-01T01:01:00.000Z",
}

Мне нужно сохранить все значения, которые были установлены на 0 или false.

Я хотел бы усовершенствовать этот метод removeNull с использованием метода ES6, но пока мне не удалосьсделайте это.

Я также попробовал метод старой школы, который использовался для этого Как глубоко удалить нулевые значения, пустые объекты и пустой массив из объекта

itemToBool = item => {
  if (typeof item !== 'object' || item === null) return item;
  const cleanedItem = cleanObject(item);
  return Object.keys(cleanedItem).length !== 0 && cleanedItem;
};

cleanObject = obj => {
  if (Array.isArray(obj)) {
    const newArr = obj.map(itemToBool).filter(Boolean);
    return newArr.length && newArr;
  }
  const newObj = Object.entries(obj).reduce((a, [key, val]) => {
    const newVal = itemToBool(val);
    if (newVal !== null || newVal === false) a[key] = newVal;
    return a;
  }, {});
  return Object.keys(newObj).length > 0 && newObj;
};

но тоже не получается.

Ответы [ 4 ]

0 голосов
/ 21 июня 2019

Вы можете использовать JSON.stringify и его необязательный второй аргумент replacer, но учтите, что следующий код удаляет null и undefined.

const sanitize = (obj) => {
  return JSON.parse(JSON.stringify(obj, (key, value) => {
    return (value === null ? undefined : value);
  }));
};

const obj = {
  "a": "string not empty",
  "b": {
    "c": "string not empty",
  },
  "d": {
    "e": false,
    "f": 0,
    "g": true,
    "h": 10
  },
  "i": {
    "j": 0,
    "k": null
  },
  "l": {
    "m": null
  },
  "n": {
    "o": 1,
    "p": "string (not empty)",
    "q": {}
  },
  "r": [],
  "l": "2000-01-01T01:01:00.000Z",
}

console.log(sanitize(obj))
0 голосов
/ 17 сентября 2018

Если вы не хотите видоизменять объект и вам нужна новая копия, вы можете преобразовать объект в формат json, проанализировать его и отфильтровать во время анализа. Если вам не нужен исходный объект, вы можете переопределить результат в той же ссылке. Это может быть не эффективный подход, но, очевидно, намного чище, а не саморекурсивный подход.

var obj = {
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0,
        "k": null
    },
    "l": {
        "m": null
    },
    "n": {
        "o": 1,
        "p": "string (not empty)",
        "q": {}
    },
    "r": [],
    "s": {"t": null},
    "u": [null, {"v": {}}]
}
function copyNonEmpty(o) {
  let ignores = [null, undefined, ""],
    isNonEmpty = d => !ignores.includes(d) && (typeof(d) !== "object" || Object.keys(d).length)
  return JSON.parse(JSON.stringify(o), function(k, v) {
    if (isNonEmpty(v))
      return v;
  });
}

var res = copyNonEmpty(obj);
console.log(JSON.stringify(res, null, 4));

Если значение Object или Array, то typeof вернет object, а Object.keys вернет массив ключей для обоих случаев ("0", "1", 2 ... в случае массив), а длина массива (из ключей) будет 0, если это пустой массив или объект. Таким образом, условно, он не должен (null, undefined или "") и (или не object/array ИЛИ object/array, который не пуст, и тогда вы можете взять это значение.

0 голосов
/ 19 сентября 2018

Благодаря Нине Шольц, моя улучшенная версия будет:

cleanObject = function(object) {
    Object
        .entries(object)
        .forEach(([k, v]) => {
            if (v && typeof v === 'object')
                cleanObject(v);
            if (v && 
                typeof v === 'object' && 
                !Object.keys(v).length || 
                v === null || 
                v === undefined ||
                v.length === 0
            ) {
                if (Array.isArray(object))
                    object.splice(k, 1);
                else if (!(v instanceof Date))
                    delete object[k];
            }
        });
    return object;
}
0 голосов
/ 17 сентября 2018

Вы могли бы пойти прямым путем, перебирая пары ключ / значение объекта и сначала перебирая вложенные итерируемые объекты, а затем удаляя ненужные ключи.

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

var object = { a: "string not empty", b: { c: "string not empty" }, d: { e: false, f: 0, g: true, h: 10 }, i: { j: 0, k: null }, l: { m: null }, n: { o: 1, p: "string (not empty)", q: {} }, r: [{ foo: null }] };

console.log(clean(object));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...