如何使用 lodash 在 TypeScript 中处理复杂的嵌套数据转换?

问题描述 投票:0回答:1

我正在开发一个 TypeScript 项目,我需要对深度嵌套的 JSON 数据执行复杂的转换。我正在使用 lodash 来实现实用功能,但我在以下场景中遇到了困难:

{
  "users": [
    {
      "id": 1,
      "name": "Alice",
      "details": {
        "age": 25,
        "address": {
          "city": "Wonderland",
          "postalCode": "12345"
        }
      }
    },
    {
      "id": 2,
      "name": "Bob",
      "details": {
        "age": 30,
        "address": {
          "city": "Builderland",
          "postalCode": "67890"
        }
      }
    }
  ]
}

我需要:

  • 扁平化结构,使每个用户的数据都是一个单一对象,其属性包括扁平化格式的用户地址。
  • 将数据转换为新的结构,其中用户的邮政编码作为键,值是包含姓名、年龄和城市的对象。

问题:

  • 是否有更有效的方法使用 lodash 来展平和转换这些数据?

  • 如何提高这段代码的可读性和可维护性,特别是当数据结构变得更加复杂时?

这是我尝试过的:

import _ from 'lodash'; 

const nestedData = {
  users: [
    {
      id: 1,
      name: "Alice",
      details: {
        age: 25,
        address: {
          city: "Wonderland",
          postalCode: "12345"
        }
      }
    },
    {
      id: 2,
      name: "Bob",
      details: {
        age: 30,
        address: {
          city: "Builderland",
          postalCode: "67890"
        }
      }
    }
  ]
};

// Flattening data
const flattenedData = _.flatMap(nestedData.users, user => ({
  id: user.id,
  name: user.name,
  age: user.details.age,
  city: user.details.address.city,
  postalCode: user.details.address.postalCode
}));

console.log('Flattened Data:', flattenedData);

// Transforming data
const transformedData = _.mapValues(
  _.keyBy(flattenedData, 'postalCode'),
  ({ name, age, city }) => ({ name, age, city })
);

console.log('Transformed Data:', transformedData);
javascript node.js typescript lodash node-modules
1个回答
0
投票

如果您主要关心的是性能,我建议跳过 lodash 并执行如下操作。

我假设您的数据如下所示:

interface User {
    id: number;
    name: string;
    details: {
        age: number;
        address: {
            city: string;
            postalCode: string;
        }
    }
}

如果是这样,您可以使用以下方法:

function postCodeMap(users: User[]) {
    type UserMapped = { name: User['name'], age: User['details']['age'], city: User['details']['address']['city'] };
    const postCodeMap = new Map<string, Array<UserMapped>>();
    users.forEach(u => { // iterate the array only one time
        const postalCode = u.details.address.postalCode;
        if (postCodeMap.has(postalCode)) {
            const prev = postCodeMap.get(postalCode);
            postCodeMap.set(postalCode, [
                ...prev ? prev : [],
                {
                    name: u.name,
                    age: u.details.age,
                    city: u.details.address.city
                }
            ]);
        } else {
            postCodeMap.set(postalCode, [
                {
                    name: u.name,
                    age: u.details.age,
                    city: u.details.address.city
                }
            ]);
        }
    });
    return postCodeMap;
}

结果如下所示:

const result = postCodeMap(nestedData.users);
console.log(result);

/*
Map (2) {"12345" => [{
  "name": "Alice",
  "age": 25,
  "city": "Wonderland"
}], "67890" => [{
  "name": "Bob",
  "age": 30,
  "city": "Builderland"
}]}
*/

如您所见,只需遍历一次数组即可达到预期结果,并且不需要添加外部库,这将帮助您使应用程序尽可能小。

© www.soinside.com 2019 - 2025. All rights reserved.