返回

从另一个数组的值创建新数组:标签键值对转换的详细指南

javascript

从另一个数组的值创建新数组:标签键值对转换

简介

在数据处理任务中,经常需要从现有的数据集中提取特定信息并以不同的格式重新组织。本文将探讨如何从包含嵌套键值对的数组中创建一个新数组,其中键值对来自嵌套数组的字段。

问题:从标签数组创建键值对

假设我们有一个数组,其中每个元素包含一个嵌套的 "metadata" 对象,其中包含一个 "tags" 数组。目标是创建一个新数组,其中键为 "tags" 数组中的 "type" 值,值为 "tags" 数组中的 "value" 值。

输入数组示例:

[
    {
        fileName: 'Home_AIT_Spraying-1_29062023.agdata',
        fileType: 'AgData',
        metadata: {
            tags: [
                {
                    type: 'Field',
                    value: 'Home',
                    uniqueId: null,
                },
                {
                    type: 'Farm',
                    value: 'OTF',
                    uniqueId: null,
                },
                {
                    type: 'Grower',
                    value: 'Jim Smith',
                    uniqueId: null,
                }
            ],
        },
    },
    {
        fileName: 'AIT_AIT_Spraying-1_30062023.agdata',
        fileType: 'AgData',
        metadata: {
            tags: [
                {
                    type: 'Field',
                    value: 'Oscar',
                    uniqueId: null,
                },
                {
                    type: 'Farm',
                    value: 'OTF',
                    uniqueId: null,
                },
                {
                    type: 'Grower',
                    value: 'Jasper Jones',
                    uniqueId: null,
                }
            ],
        },
    }
]

解决方案:利用 Array.reduce()

要从 "tags" 数组中提取键值对,我们可以使用 JavaScript 的 Array.reduce() 方法。该方法可以迭代数组,累积一个单一的结果值。

以下代码演示了如何使用 Array.reduce() 实现我们的目标:

const output = input.reduce((acc, curr) => {
  const newObj = {};
  curr.metadata.tags.forEach((tag) => {
    newObj[tag.type] = tag.value;
  });
  acc.push(newObj);
  return acc;
}, []);

代码解释:

  • 回调函数接受两个参数:acc(累加器)和 curr(当前元素)。
  • 在回调函数中,创建一个新对象 newObj 来存储键值对。
  • 遍历 curr 元素中的 "tags" 数组,将 "type" 和 "value" 值存储为 newObj 的键值对。
  • newObj 推入累加器 acc 中,然后返回累加器。
  • reduce() 迭代数组中的所有元素,将每个元素的键值对添加到累加器中。

期望输出:

[
    {
        Field: 'Home',
        Farm: 'OTF',
        Grower: 'Jim Smith',
    },
    {
        Field: 'Oscar',
        Farm: 'OTF',
        Grower: 'Jasper Jones',
    },
];

常见问题解答

  • 为什么不直接使用 map()filter() 方法?

map()filter() 是用于数组转换的更常见的 JavaScript 方法。但是,reduce() 更适合此任务,因为它允许我们累积一个单一的结果值,而不是返回一个新的数组。

  • 是否可以对输出对象进行排序?

是的,可以使用 Object.entries()Array.sort() 方法对输出对象进行排序。

  • 如何处理具有相同 "type" 值的多个 "tags"?

在这种情况下,可以使用 reduce() 的第二个参数(累加器)来处理具有相同键的多个值。例如,我们可以使用 concat() 方法将值附加到一个数组中。

  • 是否存在使用 Lodash 或其他库的替代解决方案?

可以使用 Lodash 的 _.mapKeys()_.fromPairs() 函数来实现类似的结果。

  • 针对大型数据集,哪种方法更有效?

对于大型数据集,reduce() 方法通常比其他方法更有效率,因为它避免创建不必要的新数组。