I can\'t figure it out how to transform and combine 2 arrays of object.
I have this 2 arrays of objects:
const selectedCourse = [
{
\"courseTyp
Assuming, you want all items with selectedCourse
, you could take a Map
and collect all courses and later greate a new array out of the found values.
This solution includes Fish as well.
const
selectedCourse = [{ courseType: [5], id: 26, title: "Apple Tart with Apricot Glaze" }, { courseType: [3], id: 16, title: "Classic Caesar Salad" }, { courseType: [1, 2], id: 10, title: "Lobster Bisque" }, { courseType: [3], id: 16, title: "Classic Caesar Salad" }],
courseTypes = [{ name: "Hors d'oeuvres", id: 0 }, { name: "Soup", id: 1 }, { name: "Fish", id: 2 }, { name: "Salad", id: 3 }, { name: "Main course", id: 4 }, { name: "Dessert", id: 5 }],
map = selectedCourse.reduce((m, o) => o.courseType.reduce((n, id) => n.set(id, [...(n.get(id) || []), o]), m), new Map),
result = courseTypes.reduce(
(r, { name: courseName, id: courseType }) => (map.get(courseType) || []).reduce((s, courses) => s.concat({ courseType, courseName, courses }), r),
[]
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could use map
and filter
like this:
const selectedCourse = [ { "courseType": [5], "id": 26, "title": "Apple Tart with Apricot Glaze", }, { "courseType": [3], "id": 16, "title": "Classic Caesar Salad", }, { "courseType": [1,2], "id": 10, "title": "Lobster Bisque", }, { "courseType": [3], "id": 16, "title": "Classic Caesar Salad", }, ]
const courseTypes = [ {name: "Hors d'oeuvres", id: 0}, {name: "Soup", id: 1}, {name: "Fish", id: 2}, {name: "Salad", id: 3}, {name: "Main course", id: 4}, {name: "Dessert", id: 5} ];
const result = courseTypes.map(courseType => ({
courseType: courseType.id,
courseName: courseType.name,
courses: selectedCourse.filter(course => course.courseType.includes(courseType.id))
})).filter(extended => extended.courses.length);
console.log(JSON.stringify(result, null, 2));
courseTypes.map
iterates over your second input array and for each type it finds in selectedCourse
which courses match with that particular type.
It uses .filter
to collect those matches. The filter
callback uses includes
to determine if there is a match -- it returns a boolean, exactly what the filter callback expects as return value.
This filtered array is then added to an object literal that also defines the other two properties courseType
and courseName
. That new object is what the course type is mapped to. courseTypes.map
returns an array of those objects.
Finally that result may have entries that have an empty courses
array. Those are filtered out with another call to .filter
. If the length
of that courses
array is non zero, the object is kept, otherwise it is kicked out of the result.
Here is the same code made compatible with older browsers (no arrow functions, no includes
, which were introduced in ES2015):
const selectedCourse = [ { "courseType": [5], "id": 26, "title": "Apple Tart with Apricot Glaze", }, { "courseType": [3], "id": 16, "title": "Classic Caesar Salad", }, { "courseType": [1,2], "id": 10, "title": "Lobster Bisque", }, { "courseType": [3], "id": 16, "title": "Classic Caesar Salad", }, ]
const courseTypes = [ {name: "Hors d'oeuvres", id: 0}, {name: "Soup", id: 1}, {name: "Fish", id: 2}, {name: "Salad", id: 3}, {name: "Main course", id: 4}, {name: "Dessert", id: 5} ];
const result = courseTypes.map(function (courseType) {
return {
courseType: courseType.id,
courseName: courseType.name,
courses: selectedCourse.filter(function (course) {
return course.courseType.indexOf(courseType.id) > -1;
})
};
}).filter(function (extended) {
return extended.courses.length;
});
console.log(JSON.stringify(result, null, 2));
while "trincot" code is work fine for chrome and Mozila but it will not work in IE edge and IE 10 and below you need to convert it in pure javascript. below is code which will work in all browser.
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(searchElement, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
// 1. Let O be ? ToObject(this value).
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If len is 0, return false.
if (len === 0) {
return false;
}
// 4. Let n be ? ToInteger(fromIndex).
// (If fromIndex is undefined, this step produces the value 0.)
var n = fromIndex | 0;
// 5. If n ≥ 0, then
// a. Let k be n.
// 6. Else n < 0,
// a. Let k be len + n.
// b. If k < 0, let k be 0.
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(searchElement, elementK) is true, return true.
if (sameValueZero(o[k], searchElement)) {
return true;
}
// c. Increase k by 1.
k++;
}
// 8. Return false
return false;
}
});
}
var selectedCourse = [{ "courseType": [5], "id": 26, "title": "Apple Tart with Apricot Glaze" }, { "courseType": [3], "id": 16, "title": "Classic Caesar Salad" }, { "courseType": [1, 2], "id": 10, "title": "Lobster Bisque" }, { "courseType": [3], "id": 16, "title": "Classic Caesar Salad" }];
var courseTypes = [{ name: "Hors d'oeuvres", id: 0 }, { name: "Soup", id: 1 }, { name: "Fish", id: 2 }, { name: "Salad", id: 3 }, { name: "Main course", id: 4 }, { name: "Dessert", id: 5 }];
var result = courseTypes.map(function (courseType) {
return {
courseType: courseType.id,
courseName: courseType.name,
courses: selectedCourse.filter(function (course) {
return course.courseType.includes(courseType.id);
})
};
}).filter(function (extended) {
return extended.courses.length;
});
console.log(JSON.stringify(result, null, 2));