【问题标题】:Group Array of objects into 2D Array by the property of an object contained into an array通过包含在数组中的对象的属性将对象数组分组为二维数组
【发布时间】:2022-12-18 17:18:43
【问题描述】:

我有一组这样的对象:

[
  {
    "id": 1,
    "name": "Question1",
    "categories": [
      {
        "id": 20,
        "name": "Science"
      },
      {
        "id": 21,
        "name": "General Knowledge"
      },
      {
        "id": 20,
        "name": "Mathematic"
      }
    ]
  },
  {
    "id": 2,
    "name": "Question2",
    "categories": [
      {
        "id": 20,
        "name": "Science"
      }
    ]
  },
  {
    "id": 3,
    "name": "Question3",
    "categories": [
      {
        "id": 20,
        "name": "Science"
      }
    ]
  }
]

我想按对象属性将对象分组为子数组(按字母顺序排序)姓名数组的类别.

预期的输出将是:

[
  //General Knowledge
  [
    {
      "id": 1,
      "name": "Question1",
      "categories": [
        {
          "id": 20,
          "name": "Science"
        },
        {
          "id": 21,
          "name": "General Knowledge"
        },
        {
          "id": 20,
          "name": "Mathematic"
        }
      ]
    }
  ],
  //Mathematic
  [
    {
      "id": 1,
      "name": "Question1",
      "categories": [
        {
          "id": 20,
          "name": "Science"
        },
        {
          "id": 21,
          "name": "General Knowledge"
        },
        {
          "id": 20,
          "name": "Mathematic"
        }
      ]
    }
  ],
  //Science
  [
    {
      "id": 1,
      "name": "Question1",
      "categories": [
        {
          "id": 20,
          "name": "Science"
        },
        {
          "id": 21,
          "name": "General Knowledge"
        },
        {
          "id": 20,
          "name": "Mathematic"
        }
      ]
    },
    {
      "id": 2,
      "name": "Question2",
      "categories": [
        {
          "id": 20,
          "name": "Science"
        }
      ]
    },
    {
      "id": 3,
      "name": "Question3",
      "categories": [
        {
          "id": 20,
          "name": "Science"
        }
      ]
    }
  ]
]

我一直在尝试使用循环和Array.reduce(),但我没能成功。

哪一个是实现预期输出的最佳方式? 非常感谢!

【问题讨论】:

  • 你能确认你的预期输出是正确的吗?您不是说问题 1 每次只有常识,然后只有数学,然后只有科学,而不是这三个吗?
  • 预期的输出是正确的,因为每个子数组都是一个组。问题 1 重复三次(每个数组重复一次)因为它有三个类别

标签: javascript arrays sorting grouping lodash


【解决方案1】:

遍历每个对象并在该循环中遍历 categories。在 group 对象中使用每个类别名称作为键,并使用一组问题作为值

const group = {}

for (const q of questions) {
  for(const c of q.categories) {
    group[c.name] ??= []
    group[c.name].push(q)
  }
}

const output = Object.values(group)

这是一个 sn-p:

const questions =[{id:1,name:"Question1",categories:[{id:20,name:"Science"},{id:21,name:"General Knowledge"},{id:20,name:"Mathematic"}]},{id:2,name:"Question2",categories:[{id:20,name:"Science"}]},{id:3,name:"Question3",categories:[{id:20,name:"Science"}]}];

const group = {}

for (const q of questions) {
  for(const c of q.categories) {
    group[c.name] ??= []
    group[c.name].push(q)
  }
}

const output = Object.values(group)

document.querySelector("pre").innerText = JSON.stringify(output, null, 4)
<pre />

【讨论】:

    【解决方案2】:

    假设您的预期输出是正确的,这就是我所做的。我不知道这是最有效的方法,但它有效:

    const input = [
      {
        id: 1,
        name: "Question1",
        categories: [
          {
            id: 20,
            name: "Science",
          },
          {
            id: 21,
            name: "General Knowledge",
          },
          {
            id: 20,
            name: "Mathematic",
          },
        ],
      },
      {
        id: 2,
        name: "Question2",
        categories: [
          {
            id: 20,
            name: "Science",
          },
        ],
      },
      {
        id: 3,
        name: "Question3",
        categories: [
          {
            id: 20,
            name: "Science",
          },
        ],
      },
    ];
    
    // First we put all subjects into an array.
    const subjects = [];
    for (const element of input) {
      for (const categories of element.categories) {
        if (!subjects.find((e) => e === categories.name)) {
          subjects.push(categories.name);
        }
      }
    }
    
    // then we add the element to our output ordered by subjet
    const output = [];
    for (const subject of subjects) {
      const tempOutput = [];
      for (const element of input) {
        if (element.categories?.find((e) => e.name === subject)) {
          tempOutput.push(element);
        }
      }
      output.push(tempOutput);
    }
    
    console.log(output);

    【讨论】:

      【解决方案3】:
      const convert = (input) => {
              return input.reduce((acc, question) => {
                  question.categories.forEach((category) => {
                  if (!acc[category.id]) {
                      acc[category.id] = [];
                  }
                  acc[category.id].push(question);
                  });
                  return acc;
              }, []);
              };
      

      使用此功能

      【讨论】:

        猜你喜欢
        • 2013-09-06
        • 2013-06-23
        • 2020-11-19
        • 1970-01-01
        • 2018-10-08
        • 2017-01-28
        • 2019-10-01
        • 1970-01-01
        • 2014-06-08
        相关资源
        最近更新 更多