Skip to content

在JavaScript中压缩数组或对象

术语"压缩"用于描述从数组或对象中删除所有假值的过程。一般来说,您可以使用Boolean函数来过滤掉所有假值(falsenull0''undefinedNaN),从而压缩数组或对象。

压缩数组

压缩一个数组就是使用Array.prototype.filter()结合Boolean函数来实现。

const compact = arr => arr.filter(Boolean);

compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]);
// [ 1, 2, 3, 'a', 's', 34 ]

压缩对象

压缩一个对象与数组类似,但是您需要使用Object.entries()来迭代对象,然后过滤其键值对。

const compact = obj =>
  Object.fromEntries(
    Object.entries(obj).filter(([key, value]) => Boolean(value))
  );

compact({ a: 0, b: 1, c: false, d: '', e: 2, f: 'a', g: 'e' * 23, h: NaN });
// { b: 1, e: 2, f: 'a' }

深度压缩数组或对象

到目前为止,我们只对数组和对象进行了浅层压缩。如果你想要对数组或对象进行深度压缩,可以使用递归来压缩所有嵌套的数组和对象。

首先,使用Array.isArray()Array.prototype.filter()Boolean来初始化可迭代数据,以避免稀疏数组。使用Object.entries()Array.prototype.reduce(),我们可以迭代每个键,并使用适当的初始值。然后,我们可以使用Boolean来确定每个键的值的真实性,并将其添加到累加器中,如果它是真实的。最后,我们可以使用typeof来确定给定值是否为object,并再次调用函数来进行深度压缩。

const deepCompact = val => {
  const data = Array.isArray(val) ? val.filter(Boolean) : val;
  return Object.entries(data).reduce(
    (acc, [key, value]) => {
      if (Boolean(value))
        acc[key] = typeof value === 'object' ? deepCompact(value) : value;
      return acc;
    },
    Array.isArray(val) ? [] : {}
  );
};

const obj = {
  a: null,
  b: false,
  c: true,
  d: 0,
  e: 1,
  f: '',
  g: 'a',
  h: [null, false, '', true, 1, 'a', { i: 0, j: 2}],
  k: { l: 0, m: false, n: 'a', o: [0, 1] }
};
/*
{
  c: true,
  e: 1,
  g: 'a',
  h: [ true, 1, 'a', { j: 2 } ],
  k: { n: 'a', o: [1] }
}
*/