我是lodash的新手,我想使用i和j将此forloop转换为lodash,以便减少编码。
for(var i =0 ; i < students.length; i++){
for(var j = 0; j <marks.lab.length;j++){
if(students[i].sID === marks.lab[j].sID){
students[i].coding = data.lab[j].coding;
}
}
}
如果使用lodash还有其他任何优点,请告诉我。
答案 0 :(得分:2)
您可以使用keyBy()按marks.lab
缓存sID
数组作为参考。使用map返回一个新的学生数组,其中使用pick从marks.lab
缓存中获取所需的密钥,然后使用assign()添加所有学生财产。这样做可以确保students
数组不会发生变异。
var labs = _.keyBy(marks.lab, 'sID'); // cache by key
var result = _.map(students, function(student) {
return _(labs[student.sID]) // get the cache
.pick(['coding']) // This returns a new object
.assign(student); // Assigns the student object
});
var students = [
{ sID: '1', name: 'Ryan' },
{ sID: '2', name: 'Rez James' },
{ sID: '3', name: 'Hazel Charmagne' }
];
var marks = {
lab: [
{ sID: '1', coding: 'A' },
{ sID: '2', coding: 'A' },
{ sID: '3', coding: 'A' }
]
};
var labs = _.keyBy(marks.lab, 'sID'); // cache by key
var result = _.map(students, function(student) {
return _(labs[student.sID]) // get the cache
.pick(['coding']) // This returns an immutable object
.assign(student); // Assigns the student object
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>
&#13;
<强>更新强>
对于lodash 3解决方案,您只需使用lodash 3&#39; s keyBy()更改lodash 4 indexBy()。
var labs = _.indexBy(marks.lab, 'sID'); // cache by key
var result = _.map(students, function(student) {
return _(labs[student.sID]) // get the cache
.pick(['coding']) // This returns an immutable object
.assign(student); // Assigns the student object
});
var students = [
{ sID: '1', name: 'Ryan' },
{ sID: '2', name: 'Rez James' },
{ sID: '3', name: 'Hazel Charmagne' }
];
var marks = {
lab: [
{ sID: '1', coding: 'A' },
{ sID: '2', coding: 'A' },
{ sID: '3', coding: 'A' }
]
};
var labs = _.indexBy(marks.lab, 'sID'); // cache by key
var result = _.map(students, function(student) {
return _(labs[student.sID]) // get the cache
.pick(['coding']) // This returns an immutable object
.assign(student); // Assigns the student object
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&#13;
<script src="https://cdn.jsdelivr.net/lodash/3.10.1/lodash.js"></script>
&#13;
使用lodash的优势是它提供了许多已经预先编写的实用方法,这节省了资源和开发人员创建函数的时间。至于for
循环解决方案的情况,您可能会说,在更简单的情况下,简单的for
循环比使用lodash
实用程序方法更好,更易读。
如果我们谈论性能,你可能会说解决方案,你的 for
循环可能会受到性能影响,因为它是O(N ^ 2)。您可以创建一个for
循环版本来缓存marks.lab
数组,然后再次循环students
数组以获得正确的输出:
var labs = {};
var i;
for(i = 0; i < marks.lab.length; i++) {
labs[marks.lab[i].sID] = marks.lab.coding;
}
for(i = 0; i < students.length; i++) {
students[i].coding = labs[students[i].sID];
}
上述解决方案对两个循环都有O(N)。哪个更接近我上面提供的解决方案,除了上面的for
循环解决方案和此for
循环解决方案突变原始students
数组的部分。当你想重用它时,改变原始数组可能是一件坏事。让我们调整上面的for
循环解决方案,以防止改变原始数组:
var labs = {};
var result = [];
var i;
for(i = 0; i < marks.lab.length; i++) {
labs[marks.lab[i].sID] = marks.lab.coding;
}
for(i = 0; i < students.length; i++) {
result.push(Object.assign(
{ coding: labs[students[i].sID] },
students[i]
));
}
如果你将上面的for
循环解决方案与我提供的lodash
解决方案进行比较,那么它肯定会为你节省几行和编码时间。
答案 1 :(得分:1)
从概念上讲,您正尝试根据学生的ID在两个数据集之间进行连接。我不认为lodash有一个sql-esque连接,所以如果没有你可以做如下的天真O(n ^ 2)实现。
var new_students = _.map(students, function(stud){
var matching_score = _.chain(marks).filter(function(mark){
return stud.sID == mark.lab.sID;
})
.first()
.value();
var new_student = _.cloneDeep(stud);
new_student.coding = matching_score.coding;
return new_student;
});
请注意,这会返回新学生对象,并且不会改变您的旧对象。也就是说,如果你关心性能并且不介意可变性,那么进行散列连接将获得O(n)性能。
var sqljoin = function(first, second, first_on, second_on, item_maker){
var first_dict = {};
_.each(first, function(f){
var key = first_on(f);
if(! (key in first_dict) ){
first_dict[key] = f;
}
});
return _.chain(second).filter(function(s){
var key = second_on(s);
return key in first_dict;
})
.map(function(s){
var key = second_on(s);
var first_val = first_dict[key];
var second_val = s;
return item_maker(first_val, second_val);
})
.value();
};
_.mixin('sqljoin', sqljoin);