【问题标题】:How to make one array from three arrays having common fields如何从具有公共字段的三个数组中创建一个数组
【发布时间】:2020-08-18 16:23:10
【问题描述】:

我正在尝试创建一个 HTML 视图,我需要一个特定的数组模式。我有三个这样的数组:

第一个:

 classes = [
    { classid: 1, classname: "class 1" },
    { classid: 2, classname: "class 2" },
    { classid: 3, classname: "class 3" },
    { classid: 4, classname: "class 4" },
    { classid: 5, classname: "class 5" },
  ];

第二个:

 classwithSubjectIDSubjectName = [
        { classid: 1, subjectid: 10, subjectname: "Hindi" },
        { classid: 1, subjectid: 11, subjectname: "English" },
        { classid: 2, subjectid: 11, subjectname: "English" },
        { classid:3, subjectid: 12, subjectname: "GEO" },
      ];

第三:

classwithtopic = [
    {
      classid: 1,
      subjectid: 10,
      topicid: 101,
      topicname: "topic 1 of id 10",
    },
    {
      classid: 1,
      subjectid: 11,
      topicid: 102,
      topicname: "topic 1 of id 11",
    },
    {
      classid: 2,
      subjectid: 11,
      topicid: 103,
      topicname: "topic 1 of id 11",
    },
    {
      classid: 2,
      subjectid: 11,
      topicid: 104,
      topicname: "topic 2 of id 11",
    },
    {
      classid: 2,
      subjectid: 11,
      topicid: 105,
      topicname: "topic 3 of id ",
    },
    {
      classid: 2,
      subjectid: 11,
      topicid: 106,
      topicname: "topic 4 of id 11",
    },
  ];

我需要最终的数组是这样的,

finalarray = [
    {
      class_id: 1,
      class_name: "class1",
      subjects: [
        {
          subejct_id: 11,
          subejct_name: "English",
              topics: [{topicid:108,topicname: "topic 1 of id 11 "}, {topicid:107,topicname: "topic 2 of id 11 "}],
         {
          subejct_id: 10,
          subejct_name: "Hindi",
              topics: [{topicid:106,topicname: "topic 1 of id 10 "}, {topicid:107,topicname: "topic 2 of id 10 "}],
      ],
    },
    {
      class_id: 2,
      class_name: "class 2",
     subjects: [
        {
          subejct_id: 11,
          subejct_name: "English",
          topics: [{topicid:103,topicname: "topic 1 of id 11 "}, {topicid:104,topicname: "topic 2 of id 11 "}],
        },
         {
          subejct_id: 12,
          subejct_name: "Hindi",
          topics: [{topicid:100,topicname: "topic 1 of id 12 "}, {topicid:101,topicname: "topic 2 of id 12 "}],
        },
      ],
    },
    
  ];

我尝试使用reduce但没有成功。我对代码的时间复杂度没有任何问题,因为我会处理它。任何帮助将不胜感激以实现最终数组。

编辑:

正如@HereticMonkey 所问,我在另一个类似这样的阵列上尝试了这个。

selectedSubjects=[
{ subjectName: "maths", topicName: "topic1 of maths"}
{ subjectName: "maths", topicName: "topic2 of maths"}
{ subjectName: "English", topicName: "topic1 of English "}
{ subjectName: "English", topicName: "topic2 of English "}
]

在这个数组上我应用了这个

const groups = this.selectedSubjects.reduce((acc, cur) => {
      (acc[cur.subjectName] = acc[cur.subjectName] || []).push(cur.topicName);
      return acc;
    }, {}); // to group the array according to subject
    console.log(groups);

    this.array= Object.keys(groups).map((key) => ({
      SubjectName: key,
      topics: groups[key],
    }));

在这之后我得到的结果是:

array=[
{SubjectName: "maths"
topics:["topic1 of maths", "topic2 of maths "]
},
{SubjectName: "English"
topics:["topic1 of English", "topic2 of English"]
}
]

但我不知道如何在三个数组上应用它。

【问题讨论】:

  • 太好了,你的尝试在哪里?
  • 请使用reduce展示您的尝试;您可能已经很接近了,我们可以节省时间来纠正您的尝试,而不是从头开始编写新代码。
  • @HereticMonkey 更新
  • @NinaScholz 更新
  • test_2 来自哪里?你真的希望你的最终数组删除没有主题或主题不包含主题的类吗?你真的想用subejct 代替subjectclass_id 代替classId 吗?也许您可以清理您的示例并详细说明要求。

标签: javascript arrays typescript


【解决方案1】:

您可以通过映射和过滤所需部分来采用分类方法。

const
    classes = [{ classid: 1, classname: "class 1" }, { classid: 2, classname: "class 2" }, { classid: 3, classname: "class 3" }, { classid: 4, classname: "class 4" }, { classid: 5, classname: "class 5" }],
    classwithSubjectIDSubjectName = [{ classid: 1, subjectid: 10, subjectname: "Hindi" }, { classid: 1, subjectid: 11, subjectname: "English" }, { classid: 2, subjectid: 11, subjectname: "English" }, { classid: 3, subjectid: 12, subjectname: "GEO" }],
    classwithtopic = [{ classid: 1, subjectid: 10, topicid: "t1", topicname: "topic 1 of id 10" }, { classid: 1, subjectid: 11, topicid: "t3", topicname: "topic 1 of id 11" }, { classid: 2, subjectid: 11, topicid: "t1", topicname: "topic 1 of id 11" }, { classid: 2, subjectid: 11, topicid: "t1", topicname: "topic 2 of id 11" }, { classid: 2, subjectid: 11, topicid: "t1", topicname: "topic 3 of id " }, { classid: 2, subjectid: 11, topicid: "t1", topicname: "topic 4 of id 11" }],
    result = classes.map(({ classid: class_id, classname: class_name }) => ({
        class_id,
        class_name,
        subjects: classwithSubjectIDSubjectName
            .filter(q => q.classid === class_id)
            .map(({ subjectid: subject_id, subjectname: subject_name }) => ({
                subject_id,
                subject_name,
                topics: classwithtopic
                    .filter(q => q.classid === class_id && q.subjectid === subject_id)
                    .map(({ topicid: topic_id }) => ({
                        topic_id
                    }))
            }))
    }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

一种稍微快一点的方法,它采用对象而不是过滤。

const
    classes = [{ classid: 1, classname: "class 1" }, { classid: 2, classname: "class 2" }, { classid: 3, classname: "class 3" }, { classid: 4, classname: "class 4" }, { classid: 5, classname: "class 5" }],
    classwithSubjectIDSubjectName = [{ classid: 1, subjectid: 10, subjectname: "Hindi" }, { classid: 1, subjectid: 11, subjectname: "English" }, { classid: 2, subjectid: 11, subjectname: "English" }, { classid: 3, subjectid: 12, subjectname: "GEO" }],
    classwithtopic = [{ classid: 1, subjectid: 10, topicid: "t1", topicname: "topic 1 of id 10" }, { classid: 1, subjectid: 11, topicid: "t3", topicname: "topic 1 of id 11" }, { classid: 2, subjectid: 11, topicid: "t1", topicname: "topic 1 of id 11" }, { classid: 2, subjectid: 11, topicid: "t1", topicname: "topic 2 of id 11" }, { classid: 2, subjectid: 11, topicid: "t1", topicname: "topic 3 of id " }, { classid: 2, subjectid: 11, topicid: "t1", topicname: "topic 4 of id 11" }],

    groupBy = (array, key) => array.reduce((r, o) => {
        const k = Array.isArray(key) ? key.map(k => o[k]).join('|') : o[key];
        (r[k] = r[k] || []).push(o);
        return r;
    }, {}),
    classSubject = groupBy(classwithSubjectIDSubjectName, 'classid'),
    classSubjectTopic = groupBy(classwithtopic, ['classid', 'subjectid']),

    result = classes.map(({ classid: class_id, classname: class_name }) => ({
        class_id,
        class_name,
        subjects: classSubject[class_id]?.map(({ subjectid: subject_id, subjectname: subject_name }) => ({
            subject_id,
            subject_name,
            topics: classSubjectTopic[[class_id, subject_id].join('|')]?.map(({ topicid: topic_id }) => ({
                topic_id
            }))
        }))
    }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    除非性能是一个大问题,否则我会使用 map()filter() 的组合来生成最终数组,可能像这样:

    const finalArray = classes.map(c => ({
        class_id: c.classid,
        class_name: c.classname,
        subjects: classwithSubjectIDSubjectName.filter(s => s.classid === c.classid).map(s => ({
            subejct_id: s.subjectid,
            subejct_name: s.subjectname,
            topics: classwithtopic.filter(t => t.classid === c.classid && t.subjectid === s.subjectid
            ).map(t => ({
                topicid: t.topicid,
                topicname: t.topicname
            }))
        }))
    }))
    

    产生以下输出:

    [
      {
        "class_id": 1,
        "class_name": "class 1",
        "subjects": [
          {
            "subejct_id": 10,
            "subejct_name": "Hindi",
            "topics": [
              {
                "topicid": "t1",
                "topicname": "topic 1 of id 10"
              }
            ]
          },
          {
            "subejct_id": 11,
            "subejct_name": "English",
            "topics": [
              {
                "topicid": "t3",
                "topicname": "topic 1 of id 11"
              }
            ]
          }
        ]
      },
      {
        "class_id": 2,
        "class_name": "class 2",
        "subjects": [
          {
            "subejct_id": 11,
            "subejct_name": "English",
            "topics": [
              {
                "topicid": "t1",
                "topicname": "topic 1 of id 11"
              },
              {
                "topicid": "t1",
                "topicname": "topic 2 of id 11"
              },
              {
                "topicid": "t1",
                "topicname": "topic 3 of id "
              },
              {
                "topicid": "t1",
                "topicname": "topic 4 of id 11"
              }
            ]
          }
        ]
      },
      {
        "class_id": 3,
        "class_name": "class 3",
        "subjects": [
          {
            "subejct_id": 12,
            "subejct_name": "GEO",
            "topics": []
          }
        ]
      },
      {
        "class_id": 4,
        "class_name": "class 4",
        "subjects": []
      },
      {
        "class_id": 5,
        "class_name": "class 5",
        "subjects": []
      }
    ]
    

    我很难判断这是否正是你想要的,因为你的示例结果与你的示例输入不一致,但希望这足以让你感动。祝你好运!

    Playground link to code

    【讨论】:

    • 谢谢,这个答案也很有帮助,但我在上面得到了正确答案。感谢您的努力。
    猜你喜欢
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2020-07-06
    相关资源
    最近更新 更多