簡體   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