繁体   English   中英

使用reduce方法的Javascript转换数组

[英]Javascript transform array using reduce method

我正在尝试以如下形式转换一组对象:

const categories = [{
    "category": "Category 1",
    "desc": "Description 1 of the category 1"
  },
  {
    "category": "Category 1",
    "desc": "Description 2 of the category 1"
  }, {
    "category": "Category 2",
    "desc": "Description 1 of the category 2"
  },
  {
    "category": "Category 2",
    "desc": "Description 2 of the category 2"
  },
  {
    "category": "Category 3",
    "desc": "Description 1 of the category 3"
  }, {
    "category": "Category 3",
    "desc": "Description 2 of the category 3"
  }
];

到表单(所需的结果集);

[
  {
    "category": "Category 1",
    "desriptionList": [
      {
        "desc": "Description 1 of the category 1"
      },
      {
        "desc": "Description 2 of the category 1"
      }
    ]
  },
  {
    "category": "Category 2",
    "desriptionList": [
      {
          "error": "Description 1 of the category 2"
      },
      {
          "error": "Description 2 of the category 2"
      },
    ]
  },
   {
    "category": "Category 3",
    "desriptionList": [
      {
          "error": "Description 1 of the category 3"
      },
      {
          "error": "Description 2 of the category 3"
      },
    ]
  }
]

使用reduce方法:

const result = categories.reduce((acc, item) => {
  return [{
    ...acc,
    'category': item.category,
    'desriptionList': item.desc
  }]
}, [])

但似乎我以错误的方式在错误的地方使用了累加器,因为有一个奇怪的输出;

[{
  0: {
    0: { ... },
    category: "Category 3",
    desriptionList: "Description 1 of the category 3"
  },
  category: "Category 3",
  desriptionList: "Description 2 of the category 3"
}]

代码笔

保持简单并使用 Array.reduce() 和 Array.findIndex 遍历每个对象并决定是否应将其数据添加到累加器中的现有对象,或者是否应创建并推送新对象。

 const categories=[{category:"Category 1",desc:"Description 1 of the category 1"},{category:"Category 1",desc:"Description 2 of the category 1"},{category:"Category 2",desc:"Description 1 of the category 2"},{category:"Category 2",desc:"Description 2 of the category 2"},{category:"Category 3",desc:"Description 1 of the category 3"},{category:"Category 3",desc:"Description 2 of the category 3"}]; const result = categories.reduce(( acc, cur ) => { let idx = acc.findIndex( obj => obj.category === cur.category ) if( idx > -1 ) { acc[idx].descriptionList.push(cur.desc) } else { acc.push( { category: cur.category, descriptionList: [ cur.desc ] } ) } return acc }, []) console.log(result)

"!target.descriptionList.includes(curr)" 条件确保每个类别没有重复的 desc。 如果您觉得没有必要,请随意删除它。

const categories = [{
    "category": "Category 1",
    "desc": "Description 1 of the category 1"
  },
  {
    "category": "Category 1",
    "desc": "Description 2 of the category 1"
  }, {
    "category": "Category 2",
    "desc": "Description 1 of the category 2"
  },
  {
    "category": "Category 2",
    "desc": "Description 2 of the category 2"
  },
  {
    "category": "Category 3",
    "desc": "Description 1 of the category 3"
  }, {
    "category": "Category 3",
    "desc": "Description 2 of the category 3"
  }
];

const newArr = categories.reduce((acc, curr) => {
    let target = acc.find(element => element.category === curr.category);

    if (target) {
        if (!target.descriptionList.includes(curr)) {
            delete curr.category;
            target.descriptionList.push(curr);
        }
    } else {
        acc.push({
            category: curr.category,
            descriptionList: [{ desc: curr.desc }]
        })
    }

    return acc
}, []);

console.log('newArr: ' + JSON.stringify(newArr));

输出

newArr: [
  {
    "category": "Category 1",
    "descriptionList": [
      {
        "desc": "Description 1 of the category 1"
      },
      {
        "desc": "Description 2 of the category 1"
      }
    ]
  },
  {
    "category": "Category 2",
    "descriptionList": [
      {
        "desc": "Description 1 of the category 2"
      },
      {
        "desc": "Description 2 of the category 2"
      }
    ]
  },
  {
    "category": "Category 3",
    "descriptionList": [
      {
        "desc": "Description 1 of the category 3"
      },
      {
        "desc": "Description 2 of the category 3"
      }
    ]
  }
]

由于您需要使用将desc分组到类别,因此您将使用一个对象作为累加器。 在每次迭代中,将累加器 ( acc ) 扩展到一个新对象中,并添加当前category

要创建或更新类别的对象,请添加category ,并传播该category先前实例( undefined被忽略),添加desriptionList ,并传播先前的desriptionList (如果没有,则为后备),并添加当前的desc项。

使用Object.values()转换为数组。

 const categories = [{"category":"Category 1","desc":"Description 1 of the category 1"},{"category":"Category 1","desc":"Description 2 of the category 1"},{"category":"Category 2","desc":"Description 1 of the category 2"},{"category":"Category 2","desc":"Description 2 of the category 2"},{"category":"Category 3","desc":"Description 1 of the category 3"},{"category":"Category 3","desc":"Description 2 of the category 3"}]; const result = Object.values(categories.reduce((acc, { category, desc }) => ({ ...acc, [category]: { ...acc[category], category, desriptionList: [ ...(acc[category]?.desriptionList || []), { desc } ] } }), {})) console.log(result)

另一种选择是将类别分组为 Map,然后使用Array.from()将 Map 转换为数组。

 const categories = [{"category":"Category 1","desc":"Description 1 of the category 1"},{"category":"Category 1","desc":"Description 2 of the category 1"},{"category":"Category 2","desc":"Description 1 of the category 2"},{"category":"Category 2","desc":"Description 2 of the category 2"},{"category":"Category 3","desc":"Description 1 of the category 3"},{"category":"Category 3","desc":"Description 2 of the category 3"}]; const result = Array.from( categories.reduce((acc, { category, desc }) => { if (!acc.has(category)) acc.set(category, []); // initialize the category with an empty array acc.get(category).push({ desc }) // push current desc into the array return acc; }, new Map()), ([category, desriptionList]) => ({ category, desriptionList }) // convert to an array ) console.log(result)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM