【问题标题】:Create new object from two other by matching values in JavaScript通过匹配 JavaScript 中的值从其他两个创建新对象
【发布时间】:2020-09-11 09:25:40
【问题描述】:

重点是从现有的 listOfStudents 和 homeworkResults 对象创建新对象,这些对象与电子邮件值匹配。目标是只使用 Javascript。

以如下开头的新对象示例:

{
name: 'John',
email: 'john@gmail.com',
results: [
        {
            topic: 'HTML Basics',
            success: true
        },
        {
            topic: 'CSS Basics',
            success: false
        }
]   
},
{
name: 'Jane',
email: 'jane@gmail.com',
results: [
        {
            topic: 'HTML Basics',
            success: true
        },
        {
            topic: 'CSS Basics',
            success: true
        }
]   
}

这是我的代码示例。 addHwResults 功能有问题,因为它不排除其他学生的 hwResults。

var listOfStudents = [ 
{ name: 'John', email: 'john@gmail.com' }, 
{ name: 'Jane', email: 'jane@gmail.com' }
];

var hwResults = [ 
{ topic: 'HTML Basics', results: [ { email: 'john@gmail.com', success: true }, { email: 'jane@gmail.com', success: true } ] }, 
{ topic: 'CSS Basics', results: [ { email: 'john@gmail.com', success: false }, { email: 'jane@gmail.com', success: true } ] }
];

function Stud(name, email) {
	const hwResults = [];
	this.addHwResult = function(topic, success) {
		const result = {
			topic: topic,
			success: success
		};
		hwResults.push(result);
	}
	this.getHomeworkResult = function() {
		return hwResults;
	}
}

function Lab(studentsList){
	const stud = new Stud();

	this.printStudList = function() {
		studentsList.forEach(el => {
			console.log(stud.getHomeworkResult());
		});
	}

	this.addHwResults = function(objGet) {

		objGet.results.forEach(el => {
			const resultByEmail = studentsList.find(elem => elem.email === el.email);
				stud.addHwResult(objGet.topic, el.success);
		});

	}

}

const lab = new Lab(listOfStudents);
lab.addHwResults(hwResults[0]);
lab.addHwResults(hwResults[1]);
lab.printStudList();

错误的结果如下:

enter image description here

【问题讨论】:

  • "出了点问题" - 请您更具体地说明什么不起作用?
  • 你找到了 const resultByEmail 和什么?你不使用它。这很奇怪。
  • 我多次编辑了这段代码,在这个版本中它没有被使用,但应该为了通过电子邮件结果过滤
  • 您还没有为每个学生创建一个 Stud 对象,并且 Stud 对象不输出姓名和电子邮件。对象的结构是不完整的,输出和数据结构之间的生成也是如此。实际要求是什么?需要什么样的设计?仅修改 addHwResult 以生成输出将需要绕开这种情况,这违背了使用定义的对象的目的

标签: javascript oop object foreach find


【解决方案1】:

维护 { [email]=>Stud objects } 的对象映射。
迭代原始 studentList 对象并使用 [email] 作为 Stud 对象查找的键:

var listOfStudents = [ 
{ name: 'John', email: 'john@gmail.com' }, 
{ name: 'Jane', email: 'jane@gmail.com' }
];

var hwResults = [ 
{ topic: 'HTML Basics', results: [ { email: 'john@gmail.com', success: true }, { email: 'jane@gmail.com', success: true } ] }, 
{ topic: 'CSS Basics', results: [ { email: 'john@gmail.com', success: false }, { email: 'jane@gmail.com', success: true } ] }
];

function Stud(name, email) {
	const hwResults = [];
	this.addHwResult = function(topic, success) {
		const result = {
			topic: topic,
			success: success
		};
		hwResults.push(result);
	}
	this.getHomeworkResult = function() {
		return hwResults;
	}
}

function Lab(studentsList){
	const studs = Object.fromEntries(studentsList.map(({name,email})=>[email,new Stud(name,email)]));

	this.printStudList = function() {
		studentsList.forEach(({name, email}) => {
			console.log({ name, email, results: studs[email].getHomeworkResult()});
		});
	}

	this.addHwResults = function(objGet) {

		objGet.results.forEach(({email,success}) => {
				studs[email].addHwResult(objGet.topic, success);
		});

	}

}

const lab = new Lab(listOfStudents);
lab.addHwResults(hwResults[0]);
lab.addHwResults(hwResults[1]);
lab.printStudList();

创建学生对象映射,遍历所有结果并填充学生结果列表。将对象映射解包到列表中。

var listOfStudents = [ 
{ name: 'John', email: 'john@gmail.com' }, 
{ name: 'Jane', email: 'jane@gmail.com' },
{ name: 'failure', email: 'wat@aol.com' },
{ name: 'tryhard', email: 'imcool@hotmail.com' }
];

var hwResults = [ 
{ topic: 'HTML Basics', results: [ { email: 'john@gmail.com', success: true }, { email: 'jane@gmail.com', success: true } ] }, 
{ topic: 'CSS Basics', results: [ { email: 'john@gmail.com', success: false }, { email: 'jane@gmail.com', success: true }, { email: 'imcool@hotmail.com', success: false } ] }
];

const stuMap = Object.fromEntries(
  listOfStudents.map(x=>[x.email,{...x, results: []}]) )
hwResults.forEach( ({topic,results})=>
  results.forEach( ({email,success})=>
    stuMap[email].results.push({topic,success}) ))

console.log(
Object.values(stuMap)
)

【讨论】:

  • 您的解决方案很好。但是我的任务是使用addHwResult 函数。还有const lab = new Lab(listOfStudents); lab.addHwResults(hwResults[0]); lab.addHwResults(hwResults[1]); lab.printStudList();
  • 我基本上将您需要做的事情浓缩为 2 个理解。应该相对容易地将 2 个映射步骤插入或调整到您的 2 个对象包装结构中。每个映射步骤很可能包含在您创建的每个对象类型中
  • 我认为在这种情况下使用 flatMap 或 map 并不重要——结果是一样的
  • @Isa 它应该,或者在“tryhard”示例的情况下,您将得到不正确的结果。原件中没有提供,但每封电子邮件都出现在每个结果中是没有意义的。否则你为什么需要匹配(查找)?
  • @user120242 你说得对,我没注意到'tryhard'
猜你喜欢
  • 2020-11-18
  • 1970-01-01
  • 2018-07-13
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多