从具有 Javascript 的另一个对象获取具有唯一对 (key:value) 的新对象

Obtain a new object with unique pair (key:value) from another object with Javascript

我有一些列出教师、科目和学生的数据。我想创建一个 table,其中包含与教师关联的科目,其中不得有任何重复对,但如果关联的对不相同,则可能会有重复的教师或重复的科目。这将是数据:

const data =
[
    {
        "teacher": "John Doe",
        "subject": "Maths",
        "student": "student1"
    },
    {
        "teacher": "John Doe",
        "subject": "Maths",
        "student": "student2"
    },
    {
        "teacher": "John Doe",
        "subject": "Art",
        "student": "student1"
    },
    {
        "teacher": "Robert Wilson",
        "subject": "History",
        "student": "student1"
    },
    {
        "teacher": "John Doe",
        "subject": "Music",
        "student": "student1"
    },
    {
        "teacher": "Mark Smith",
        "subject": "Maths",
        "student": "student2"
    },
    {
        "teacher": "Mary Martin",
        "subject": "Science",
        "student": "student1"
    },
    {
        "teacher": "Mary Martin",
        "subject": "Spanish",
        "student": "student1"
    },
    {
        "teacher": "Paula Wilson",
        "subject": "Band",
        "student": "student1"
    },
    {
        "teacher": "Mark Smith",
        "subject": "Band",
        "student": "student2"
    }
]

我试过使用以下代码:

var subjectDict = {}
    data.forEach (x => {
        subjectDict [x.subject] = x.teacher
    })

    var teacherRow = Object.values (subjectDict)
    var subjects = Object.keys (subjectDict)

但是输出不准确,因为它只给了我每个科目一次,即使它是由两位不同的老师教的(乐队或数学应该出现两次,与不同的老师相关)。

我用我试过的东西创建了一个 jsfiddle:

https://jsfiddle.net/soleuil/f2r70Lte/1/

解决方案应该给我一个table,其中第一行应该用第一个元素填充,最后一行应该用第二个元素填充(考虑到顺序可以不同):

First Row : Second Row
"Maths":"John Doe"
"Art":"John Doe"
"History":"Robert Wilson"
"Music":"John Doe"
"Maths":"Mark Smith"
"Science":"Mary Martin"
"Spanish": "Mary Martin"
"Band":"Paula Wilson"
"Band":"Mark Smith"

提前致谢。

这将为您提供主题作为键以及一系列相关教师的输出:

{
  "Maths": [ "John Doe", "Mark Smith" ],
  "Art": [ "John Doe" ],
  "History": [ "Robert Wilson" ],
  "Music": [ "John Doe" ],
  "Science": [ "Mary Martin" ],
  "Spanish": [ "Mary Martin" ],
  "Band": [ "Paula Wilson", "Mark Smith" ]
}

const data = [ { "teacher": "John Doe", "subject": "Maths", "student": "student1" }, { "teacher": "John Doe", "subject": "Maths", "student": "student2" }, { "teacher": "John Doe", "subject": "Art", "student": "student1" }, { "teacher": "Robert Wilson", "subject": "History", "student": "student1" }, { "teacher": "John Doe", "subject": "Music", "student": "student1" }, { "teacher": "Mark Smith", "subject": "Maths", "student": "student2" }, { "teacher": "Mary Martin", "subject": "Science", "student": "student1" }, { "teacher": "Mary Martin", "subject": "Spanish", "student": "student1" }, { "teacher": "Paula Wilson", "subject": "Band", "student": "student1" }, { "teacher": "Mark Smith", "subject": "Band", "student": "student2" } ];

let subject_teachers = data.reduce((b, a) => {
  if (!b[a.subject]) b[a.subject] = [];
  if (b[a.subject].indexOf(a.teacher) == -1) b[a.subject].push(a.teacher);
  return b;
}, {})
console.log(subject_teachers)

使用Array#reduce:

const data = [ { "teacher": "John Doe", "subject": "Maths", "student": "student1" }, { "teacher": "John Doe", "subject": "Maths", "student": "student2" }, { "teacher": "John Doe", "subject": "Art", "student": "student1" }, { "teacher": "Robert Wilson", "subject": "History", "student": "student1" }, { "teacher": "John Doe", "subject": "Music", "student": "student1" }, { "teacher": "Mark Smith", "subject": "Maths", "student": "student2" }, { "teacher": "Mary Martin", "subject": "Science", "student": "student1" }, { "teacher": "Mary Martin", "subject": "Spanish", "student": "student1" }, { "teacher": "Paula Wilson", "subject": "Band", "student": "student1" }, { "teacher": "Mark Smith", "subject": "Band", "student": "student2" } ];

const [subjects, teachers] = data.reduce(([subjects, teachers], { subject, teacher }) => {
  const subjectIndex = subjects.indexOf(subject);
  const exists = subjectIndex >= 0 && teachers[subjectIndex] === teacher;
  return exists 
    ? [subjects, teachers] 
    : [ [...subjects, subject], [...teachers, teacher] ];
}, [ [], [] ]);

console.log(subjects);
console.log(teachers);

根据您想要的输出,我会将您的代码稍微修改为return一个对象数组。

const data =
[
    {
        "teacher": "John Doe",
        "subject": "Maths",
        "student": "student1"
    },
    {
        "teacher": "John Doe",
        "subject": "Maths",
        "student": "student2"
    },
    {
        "teacher": "John Doe",
        "subject": "Art",
        "student": "student1"
    },
    {
        "teacher": "Robert Wilson",
        "subject": "History",
        "student": "student1"
    },
    {
        "teacher": "John Doe",
        "subject": "Music",
        "student": "student1"
    },
    {
        "teacher": "Mark Smith",
        "subject": "Maths",
        "student": "student2"
    },
    {
        "teacher": "Mary Martin",
        "subject": "Science",
        "student": "student1"
    },
    {
        "teacher": "Mary Martin",
        "subject": "Spanish",
        "student": "student1"
    },
    {
        "teacher": "Paula Wilson",
        "subject": "Band",
        "student": "student1"
    },
    {
        "teacher": "Mark Smith",
        "subject": "Band",
        "student": "student2"
    }
];
var subjectDict = data.map (function(x) {
       temp = {};
       temp[x.subject] = x.teacher;
       return temp;
    });
    console.log(subjectDict);