Javascript 根据多个值将数组与其他数组组合
Javascript Combine Array by Other Array Based on Multiple Values
我有一个名为 p
的数组,它看起来像:
[
{
"Day": "Monday",
"data": [
"chest",
"triceps",
"shoulders"
]
},
{
"Day": "Tuesday",
"data": [
"back",
"biceps"
]
},
{
"Day": "Thursday",
"data": [
"legs"
]
}
]
我还有另一个数组,program
看起来像:(略读)
[
{
"target": "biceps",
"data": [
{
"name": "barbell alternate biceps curl",
"target": "biceps"
},
{
"name": "barbell lying preacher curl",
"target": "biceps"
}
]
},
{
"target": "triceps",
"data": [
{
"name": "barbell incline reverse-grip press",
"target": "triceps"
},
{
"name": "barbell lying extension",
"target": "triceps"
}
]
}
]
我需要程序来对 p.data
拥有的肌肉群进行分组。它应该看起来像:
[
{
"target": "chest tricep shoulder",
"data": [
{
"name": "chest exercise",
"target": "chest"
},
{
"name": "tricep exercise",
"target": "tricep"
},
{
"name": "shoulder exercise",
"target": "shoulder"
},
]
},
{
"target": "back biceps",
"data": [
{
"name": "back exercise",
"target": "back"
},
{
"name": "bicep exercise",
"target": "bicep"
},
]
},
]
我试过这个(基于数组排序),但不是正确的尝试:
function mapOrder(array, order, property) {
let ordered = [], unordered = [];
// Iterate over each item in the supplied array of objects, separating ordered and unordered objects into their own arrays.
array.forEach((item) => {
if (order.indexOf(item[property]) === -1) {
unordered.push(item);
} else {
ordered.push(item);
}
});
// Sort the ordered array.
ordered.sort((a, b) => {
a = a[property], b = b[property];
if (order.indexOf(a) < order.indexOf(b)) {
return -1;
} else {
return 1;
}
});
// Sort the unordered array.
unordered.sort((a, b) => {
a = a[property], b = b[property];
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
// Append the sorted, non-ordered array to the sorted, ordered array.
ordered.push(...unordered);
return ordered;
}
您可以使用以下实现:
const programs = [
{
target: "biceps",
data: [
{
name: "barbell alternate biceps curl",
target: "biceps",
},
{
name: "barbell lying preacher curl",
target: "biceps",
},
],
},
{
target: "triceps",
data: [
{
name: "barbell incline reverse-grip press",
target: "triceps",
},
{
name: "barbell lying extension",
target: "triceps",
},
],
},
];
// creates a Map which maps
// muscle => Array of exercises
const lookupTable = programs.reduce(
(map, { target, data }) => (map.set(target, data), map),
new Map()
);
const p = [
{
Day: "Monday",
data: ["chest", "triceps", "shoulders"],
},
{
Day: "Tuesday",
data: ["back", "biceps"],
},
{
Day: "Thursday",
data: ["legs"],
},
];
// for each day map the respective exercises
const result = p.map((day) => ({
// join together the muscles to a muscle group
target: day.data.join(" "),
// for each muscle get the respective exercises and put them in a list
// if a muscle does not exist (as here in this limited example) set some default value (please adjust as you please)
data: day.data.flatMap(
(muscle) =>
lookupTable.get(muscle) || {
name: `Muscle ${muscle} does not exist`,
target: muscle,
}
),
}));
console.log(JSON.stringify(result, null, 4));
.as-console-wrapper { max-height: 100% !important; top: 0; }
首先,我使用 Map
创建一个查找 table,这将允许在 O(1)
中进行快速查找,并将给定的肌肉映射到一组相应的练习,如下所示。
I use reduce()
for this but that's not required. You could just create the Map
beforehand and manually add the arrays within a loop over the array.
Map(2) {
'biceps' => [
{ name: 'barbell alternate biceps curl', target: 'biceps' },
{ name: 'barbell lying preacher curl', target: 'biceps' }
],
'triceps' => [
{ name: 'barbell incline reverse-grip press', target: 'triceps' },
{ name: 'barbell lying extension', target: 'triceps' }
]
}
然后我使用 map()
and flatMap()
为每一天创建一个训练计划,其中包含当天所有指定肌肉的所有练习。
要为肌肉群创建字符串,我们可以 join()
肌肉数组。
我有一个名为 p
的数组,它看起来像:
[
{
"Day": "Monday",
"data": [
"chest",
"triceps",
"shoulders"
]
},
{
"Day": "Tuesday",
"data": [
"back",
"biceps"
]
},
{
"Day": "Thursday",
"data": [
"legs"
]
}
]
我还有另一个数组,program
看起来像:(略读)
[
{
"target": "biceps",
"data": [
{
"name": "barbell alternate biceps curl",
"target": "biceps"
},
{
"name": "barbell lying preacher curl",
"target": "biceps"
}
]
},
{
"target": "triceps",
"data": [
{
"name": "barbell incline reverse-grip press",
"target": "triceps"
},
{
"name": "barbell lying extension",
"target": "triceps"
}
]
}
]
我需要程序来对 p.data
拥有的肌肉群进行分组。它应该看起来像:
[
{
"target": "chest tricep shoulder",
"data": [
{
"name": "chest exercise",
"target": "chest"
},
{
"name": "tricep exercise",
"target": "tricep"
},
{
"name": "shoulder exercise",
"target": "shoulder"
},
]
},
{
"target": "back biceps",
"data": [
{
"name": "back exercise",
"target": "back"
},
{
"name": "bicep exercise",
"target": "bicep"
},
]
},
]
我试过这个(基于数组排序),但不是正确的尝试:
function mapOrder(array, order, property) {
let ordered = [], unordered = [];
// Iterate over each item in the supplied array of objects, separating ordered and unordered objects into their own arrays.
array.forEach((item) => {
if (order.indexOf(item[property]) === -1) {
unordered.push(item);
} else {
ordered.push(item);
}
});
// Sort the ordered array.
ordered.sort((a, b) => {
a = a[property], b = b[property];
if (order.indexOf(a) < order.indexOf(b)) {
return -1;
} else {
return 1;
}
});
// Sort the unordered array.
unordered.sort((a, b) => {
a = a[property], b = b[property];
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
// Append the sorted, non-ordered array to the sorted, ordered array.
ordered.push(...unordered);
return ordered;
}
您可以使用以下实现:
const programs = [
{
target: "biceps",
data: [
{
name: "barbell alternate biceps curl",
target: "biceps",
},
{
name: "barbell lying preacher curl",
target: "biceps",
},
],
},
{
target: "triceps",
data: [
{
name: "barbell incline reverse-grip press",
target: "triceps",
},
{
name: "barbell lying extension",
target: "triceps",
},
],
},
];
// creates a Map which maps
// muscle => Array of exercises
const lookupTable = programs.reduce(
(map, { target, data }) => (map.set(target, data), map),
new Map()
);
const p = [
{
Day: "Monday",
data: ["chest", "triceps", "shoulders"],
},
{
Day: "Tuesday",
data: ["back", "biceps"],
},
{
Day: "Thursday",
data: ["legs"],
},
];
// for each day map the respective exercises
const result = p.map((day) => ({
// join together the muscles to a muscle group
target: day.data.join(" "),
// for each muscle get the respective exercises and put them in a list
// if a muscle does not exist (as here in this limited example) set some default value (please adjust as you please)
data: day.data.flatMap(
(muscle) =>
lookupTable.get(muscle) || {
name: `Muscle ${muscle} does not exist`,
target: muscle,
}
),
}));
console.log(JSON.stringify(result, null, 4));
.as-console-wrapper { max-height: 100% !important; top: 0; }
首先,我使用 Map
创建一个查找 table,这将允许在 O(1)
中进行快速查找,并将给定的肌肉映射到一组相应的练习,如下所示。
I use
reduce()
for this but that's not required. You could just create theMap
beforehand and manually add the arrays within a loop over the array.
Map(2) {
'biceps' => [
{ name: 'barbell alternate biceps curl', target: 'biceps' },
{ name: 'barbell lying preacher curl', target: 'biceps' }
],
'triceps' => [
{ name: 'barbell incline reverse-grip press', target: 'triceps' },
{ name: 'barbell lying extension', target: 'triceps' }
]
}
然后我使用 map()
and flatMap()
为每一天创建一个训练计划,其中包含当天所有指定肌肉的所有练习。
要为肌肉群创建字符串,我们可以 join()
肌肉数组。