【问题标题】:How would I convert an array of objects to an array of arrays of objects based on an objects value?如何根据对象值将对象数组转换为对象数组?
【发布时间】:2020-08-17 17:48:37
【问题描述】:

我有一个这样的对象数组:

const arrayOfObjects = [
{app: 'User', subpage: 'Dashboard', path: '/user/dashboard'}, 
{app: 'User', subpage: 'Profile', path: '/user/profile'},
{app: 'User', subpage: 'Settings', path: '/user/settings'},
{app: 'Library', subpage: 'Dashboard', path: '/library/dashboard'},
{app: 'Library', subpage: 'Settings', path: '/library/settings'},
{app: 'Material', subpage: 'Dashboard', path: '/material/dashboard'}]

我想要一个数组数组...其中每个“子数组”都是来自 arrayOfObjects 的原始对象数组,仅基于应用程序属性(用户、库、材料)分离。因此,新数组应如下所示:

newArray = [
     [{app: 'User', subpage: 'Dashboard', path: '/user/dashboard'}, 
      {app: 'User', subpage: 'Profile', path: '/user/profile'},
      {app: 'User', subpage: 'Settings', path: '/user/settings'}],
     [{app: 'Library', subpage: 'Dashboard', path: '/library/dashboard'},
      {app: 'Library', subpage: 'Settings', path: '/library/settings'}],
     [{app: 'Material', subpage: 'Dashboard', path: '/material/dashboard'}]
    ]

我已经用 .map 和 .forEach 尝试了几件事,但我做的最好的是将对象数组转换为数组数组...但没有我需要的分组。

【问题讨论】:

  • map 的问题在于,您最终会得到一个与输入数组具有相同数量元素的输出数组,而您在此处不希望这样做。将此作为“一体式”操作完成的“正确”数组运算符将是减少,请参阅stackoverflow.com/questions/14446511/…

标签: javascript arrays


【解决方案1】:

我们可以使用Array.find 来检查是否已经存在与app 具有相同值的元素。如果是这样,我们可以添加到该数组中。如果没有,则创建一个新数组。

const arrayOfObjects = [
{app: 'User', subpage: 'Dashboard', path: '/user/dashboard'}, 
{app: 'User', subpage: 'Profile', path: '/user/profile'},
{app: 'User', subpage: 'Settings', path: '/user/settings'},
{app: 'Library', subpage: 'Dashboard', path: '/library/dashboard'},
{app: 'Library', subpage: 'Settings', path: '/library/settings'},
{app: 'Material', subpage: 'Dashboard', path: '/material/dashboard'}]

const newArray = []

arrayOfObjects.forEach(x => {
  const existing = newArray.find(y => y[0].app == x.app);
  if (existing) {
    existing.push(x);
  }
  else {
    newArray.push([x]);
  }
});

document.write(JSON.stringify(newArray))

或者,使用Array.reduce

const arrayOfObjects = [
{app: 'User', subpage: 'Dashboard', path: '/user/dashboard'}, 
{app: 'User', subpage: 'Profile', path: '/user/profile'},
{app: 'User', subpage: 'Settings', path: '/user/settings'},
{app: 'Library', subpage: 'Dashboard', path: '/library/dashboard'},
{app: 'Library', subpage: 'Settings', path: '/library/settings'},
{app: 'Material', subpage: 'Dashboard', path: '/material/dashboard'}]

const newArray = arrayOfObjects.reduce((a,b) => {
  const existing = a.find(x => x[0].app == b.app);
  if (existing) {
    existing.push(b);
  }
  else {
    a.push([b]);
  }
  return a;
}, []);

document.write(JSON.stringify(newArray));

【讨论】:

    【解决方案2】:

    试试下面

    const arrayOfObjects = [
      {app: 'User', subpage: 'Dashboard', path: '/user/dashboard'}, 
      {app: 'User', subpage: 'Profile', path: '/user/profile'},
      {app: 'User', subpage: 'Settings', path: '/user/settings'},
      {app: 'Library', subpage: 'Dashboard', path: '/library/dashboard'},
      {app: 'Library', subpage: 'Settings', path: '/library/settings'},
      {app: 'Material', subpage: 'Dashboard', path: '/material/dashboard'}
    ]
    
    
    let result = [];
    let pushedItems = [];
    arrayOfObjects.forEach((item) => {
      if (pushedItems.includes(item.app)) {
        return;
      }
      pushedItems.push(item.app);
      let subSet = arrayOfObjects.filter((filterItem) => {
        return item.app == filterItem.app;
      });
      if (subSet && subSet.length) {
        result.push(subSet);
      }
    });
    console.log(result);
    

    【讨论】:

      【解决方案3】:

      使用array#reduce为每个app创建一个对象查找,然后使用Object.values()提取所有值。

      const arrayOfObjects = [ {app: 'User', subpage: 'Dashboard', path: '/user/dashboard'}, {app: 'User', subpage: 'Profile', path: '/user/profile'}, {app: 'User', subpage: 'Settings', path: '/user/settings'}, {app: 'Library', subpage: 'Dashboard', path: '/library/dashboard'},{app: 'Library', subpage: 'Settings', path: '/library/settings'}, {app: 'Material', subpage: 'Dashboard', path: '/material/dashboard'}],
            result = Object.values(arrayOfObjects.reduce((r,o) => {
              r[o.app] = r[o.app] || [];
              r[o.app].push({...o});
              return r;
            },{}));
      console.log(result);

      【讨论】:

        【解决方案4】:

        您可以使用扩展运算符来获取键,然后将映射与过滤器一起使用

        let allApp = [...new Set(arrayOfObjects.map(element=>element.app))];
        let result = allApp.map(filters=>arrayOfObjects.filter(element=>element.app === filters))
        
        console.log(result)
        

        【讨论】:

          【解决方案5】:
          const arrayOfObjects = [
                  { app: 'User', subpage: 'Dashboard', path: '/user/dashboard' },
                  { app: 'User', subpage: 'Profile', path: '/user/profile' },
                  { app: 'User', subpage: 'Settings', path: '/user/settings' },
                  { app: 'Library', subpage: 'Dashboard', path: '/library/dashboard' },
                  { app: 'Library', subpage: 'Settings', path: '/library/settings' },
                  { app: 'Material', subpage: 'Dashboard', path: '/material/dashboard' }]
          
              const generateArray = (array, ...args) => {
                  const newArray = new Array;
                  args.forEach(arguments => {
                      newArray.push(array.filter(arr => {
                          return arr.app.includes(arguments)
                      }))
                  })
                  return newArray
              }
          
              const newArray = generateArray(arrayOfObjects, 'User', 'Library', 'Material')
          
          
              console.log(newArray)
          

          【讨论】:

            猜你喜欢
            • 2019-04-26
            • 2019-07-29
            • 1970-01-01
            • 2022-01-23
            • 1970-01-01
            • 2020-06-15
            • 2016-03-11
            • 2021-05-03
            • 2018-12-04
            相关资源
            最近更新 更多