I am struggling with a tough requirement where I don't know how to deal with
I received one Array as below:
[{
"student": "21_A_1",
"sport": "badminton"
}, {
"student": "21_C_1",
"sport": "badminton"
}, {
"student": "21_A_2",
"sport": "badminton"
}, {
"student": "21_B_1",
"sport": "football"
}, {
"student": "21_A_2",
"sport": "football"
}]
Requirement: convert it to an array with format :
[{
"student": "21_A_1",
"sport": ["badminton"]
}, {
"student": "21_C_1",
"sport": ["badminton"]
}, {
"student": "21_A_2",
"sport": ["badminton","football"]
}, {
"student": "21_B_1",
"sport": ["football"]
}]
I found that lodash library has a feature "group by" returned quite closed result but not as expectation:
_.groupBy(array, 'student');
Result:
{
"21_A_1": [{
"student": "21_A_1",
"sport": "badminton"
}],
"21_C_1": [{
"student": "21_C_1",
"sport": "badminton"
}],
"21_A_2": [{
"student": "21_A_2",
"sport": "badminton"
}, {
"student": "21_A_2",
"sport": "football"
}],
"21_B_1": [{
"student": "21_B_1",
"sport": "football"
}]
}
Any suggestion is very appreciated.
asked Jun 14, 2018 at 13:42
Phong Vu
2,8966 gold badges30 silver badges53 bronze badges
-
Better that you construct your own algo than using lodash for this...Praveen Kumar Purushothaman– Praveen Kumar Purushothaman2018年06月14日 13:43:50 +00:00Commented Jun 14, 2018 at 13:43
3 Answers 3
You need to map the grouped items with their sport propery and build new objects with the grouping informations.
var array = [{ student: "21_A_1", sport: "badminton" }, { student: "21_C_1", sport: "badminton" }, { student: "21_A_2", sport: "badminton" }, { student: "21_B_1", sport: "football" }, { student: "21_A_2", sport: "football" }],
grouped = _(array)
.groupBy('student')
.map((group, student) => ({ student, sport: _.map(group, 'sport') }))
.value();
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
answered Jun 14, 2018 at 13:50
Nina Scholz
388k26 gold badges367 silver badges417 bronze badges
Sign up to request clarification or add additional context in comments.
1 Comment
Phong Vu
Thanks a lot for quick solutions, all are working, however, I marked this is as answer because I am using lodash. I don't know which one is the best practices, so if you guys have any best practice please keep sharing it. Because the array can be up to thousands items.
We can use '.reduce' function of array and aggregate result as below
var test = [{
"student": "21_A_1",
"sport": "badminton"
}, {
"student": "21_C_1",
"sport": "badminton"
}, {
"student": "21_A_2",
"sport": "badminton"
}, {
"student": "21_B_1",
"sport": "football"
}, {
"student": "21_A_2",
"sport": "football"
}]
const result = test.reduce((res,x)=>{
res[x.student] = res[x.student] || { student:x.student,sport:[]}
res[x.student].sport.push(x.sport)
return res;
},{})
console.log(result)
answered Jun 14, 2018 at 13:49
Jagdish Idhate
7,7529 gold badges37 silver badges58 bronze badges
Comments
Using Array.prototype.reduce() combined with Object.values():
const data = [{"student": "21_A_1","sport": "badminton"}, {"student": "21_C_1","sport": "badminton"}, {"student": "21_A_2","sport": "badminton"}, {"student": "21_B_1","sport": "football"}, {"student": "21_A_2","sport": "football"}];
const result = Object.values(
data.reduce((a, c) => ((a[c.student] = a[c.student] || {student: c.student, sport: []}).sport.push(c.sport), a), {})
);
console.log(result);
answered Jun 14, 2018 at 13:57
Yosvel Quintero
19.1k5 gold badges40 silver badges47 bronze badges
Comments
lang-js