[英]javascript - merge, combine, transform 2 different arrays of Objects
I can't figure it out how to transform and combine 2 arrays of object. 我无法弄清楚如何转换和合并2个对象数组。
I have this 2 arrays of objects: 我有这2个对象数组:
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}
]
The courseType property inside the first JSON is an array of numbers that corresponds to courseTypes index and property id in the second JSON. 第一个JSON中的courseType属性是一个数字数组,与第二个JSON中的courseTypes索引和属性ID相对应。
The result for this case should be this: 这种情况的结果应为:
const result = [
{
courseType: 1,
courseName: "Soup",
courses: [
{
"courseType": [1,2],
"id": 10,
"title": "Lobster Bisque",
}
]
},
{
courseType: 3,
courseName: "Salad",
courses: [
{
"courseType": [1,2],
"id": 10,
"title": "Lobster Bisque",
}
]
},
{
courseType: 3,
courseName: "Fish",
courses: [
{
"courseType": [3],
"id": 16,
"title": "Classic Caesar Salad",
},
{
"courseType": [3],
"id": 16,
},
]
},
{
courseType: 5,
courseName: "Main course",
courses: [
{
"courseType": [5],
"id": 26,
"title": "Apple Tart with Apricot Glaze",
}
]
}
]
The expected result have to combine the 2 arrays by filtering by courseType property. 预期的结果必须通过按CourseType属性进行过滤来合并两个数组。
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. 假设,您希望所有具有
selectedCourse
项目,都可以获取一个Map
并收集所有课程,然后从找到的值中扩充一个新数组。
This solution includes Fish as well. 此解决方案还包括Fish 。
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: 您可以像这样使用
map
和filter
:
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. courseTypes.map
遍历第二个输入数组,并为它在selectedCourse
中找到的每种类型与该特定类型匹配的课程进行迭代。
It uses .filter
to collect those matches. 它使用
.filter
收集那些匹配项。 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. filter
回调函数使用includes
来确定是否存在匹配项-它返回一个布尔值,该布尔值恰好是过滤器回调函数期望的返回值。
This filtered array is then added to an object literal that also defines the other two properties courseType
and courseName
. 然后,将这个过滤后的数组添加到一个对象常量中,该对象常量还定义了其他两个属性
courseType
和courseName
。 That new object is what the course type is mapped to. 该新对象就是课程类型所映射的对象。
courseTypes.map
returns an array of those objects. courseTypes.map
返回这些对象的数组。
Finally that result may have entries that have an empty courses
array. 最后,该结果可能包含具有空
courses
数组的条目。 Those are filtered out with another call to .filter
. 这些被另一个调用
.filter
过滤掉。 If the length
of that courses
array is non zero, the object is kept, otherwise it is kicked out of the result. 如果该
courses
数组的length
不为零,则保留该对象,否则将其踢出结果。
Here is the same code made compatible with older browsers (no arrow functions, no includes
, which were introduced in ES2015): 这是与较旧的浏览器兼容的相同代码(没有箭头功能,没有
includes
,这是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. 虽然“ trincot”代码在chrome和Mozila上工作正常,但在IE edge和IE 10及以下版本中将无法正常工作,您需要将其转换为纯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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.