返回

扁平化之谜,原来是这样

前端

今天在刷面试题,看到了对象扁平化和数组扁平化,因此写这篇文章记录一下。如果有错误,可以在评论区中指正。

对象扁平化

对象扁平化是指将对象的所有属性值都放在同一层级上,而不会再有嵌套属性。例如,下面这个对象:

const user = {
  name: '张三',
  age: 20,
  address: {
    city: '北京',
    street: '海淀区五道口'
  }
};

可以被扁平化为:

const flattenedUser = {
  name: '张三',
  age: 20,
  'address.city': '北京',
  'address.street': '海淀区五道口'
};

对象扁平化有多种实现方法,最简单的方法是使用递归。我们可以在对象中遍历每个属性,如果属性值是一个对象,我们就递归地将该对象扁平化。如果属性值不是对象,我们就将它添加到扁平化的对象中。

function flattenObject(obj) {
  const flattenedObj = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      const value = obj[key];
      if (typeof value === 'object') {
        const flattenedValue = flattenObject(value);
        for (const key in flattenedValue) {
          if (flattenedValue.hasOwnProperty(key)) {
            flattenedObj[`${key}.${key}`] = flattenedValue[key];
          }
        }
      } else {
        flattenedObj[key] = value;
      }
    }
  }
  return flattenedObj;
}

数组扁平化

数组扁平化是指将数组中的所有元素都放在同一层级上,而不会再有嵌套数组。例如,下面这个数组:

const arr = [1, 2, [3, 4], [5, [6, 7]]];

可以被扁平化为:

const flattenedArr = [1, 2, 3, 4, 5, 6, 7];

数组扁平化有多种实现方法,最简单的方法是使用递归。我们可以在数组中遍历每个元素,如果元素是一个数组,我们就递归地将该数组扁平化。如果元素不是数组,我们就将它添加到扁平化的数组中。

function flattenArray(arr) {
  const flattenedArr = [];
  for (let i = 0; i < arr.length; i++) {
    const element = arr[i];
    if (Array.isArray(element)) {
      const flattenedElement = flattenArray(element);
      flattenedArr.push(...flattenedElement);
    } else {
      flattenedArr.push(element);
    }
  }
  return flattenedArr;
}

Lodash

Lodash 是一个 JavaScript 库,它提供了许多有用的函数,其中就包括对象扁平化和数组扁平化的函数。

const flattenedUser = _.flatten(user);
const flattenedArr = _.flatten(arr);

使用 Lodash 可以大大简化对象扁平化和数组扁平化的操作。

算法原理

数组扁平化背后的算法原理其实很简单,它就是利用递归将嵌套的数组一层一层地展开,直到所有元素都处于同一层级。

function flattenArray(arr) {
  const flattenedArr = [];
  for (let i = 0; i < arr.length; i++) {
    const element = arr[i];
    if (Array.isArray(element)) {
      const flattenedElement = flattenArray(element);
      flattenedArr.push(...flattenedElement);
    } else {
      flattenedArr.push(element);
    }
  }
  return flattenedArr;
}

在上面的代码中,我们使用了一个 for 循环来遍历数组中的每个元素。如果元素是一个数组,我们就递归地调用 flattenArray 函数来将该数组扁平化。如果元素不是数组,我们就将它添加到扁平化的数组中。

这个算法的时间复杂度是 O(n),其中 n 是数组中元素的总数。这是因为算法需要遍历数组中的每个元素,并且对于每个数组元素,算法都需要检查它是否是一个数组。如果它是一个数组,算法需要递归地调用 flattenArray 函数来将该数组扁平化。

总结

对象扁平化和数组扁平化是两种非常常见的数据操作。它们在很多场景下都有用处,例如数据存储、数据传输、数据分析等。

掌握对象扁平化和数组扁平化的技巧可以帮助您在面试中脱颖而出,也可以帮助您在实际项目中编写出更简洁、更易维护的代码。