我正在尝试使用Vue
构建锻炼应用程序,您可以在其中根据选择的偏好生成锻炼程序。用户可以选择一些选项,然后单击按钮以生成锻炼。收集的数据是object
中的arrays
,每个array
包含objects
的选定选项(例如:锻炼的持续时间,难度,喜欢的锻炼)
this.generatorData = {
types: [],
style: [],
muscleGroups: [],
difficulty: [
{ title: 'Beginner', ..some properties },
{ title: 'Intermediate', .. }
]
}
我还有一组练习,它们与生成的object
具有相同的属性,但是是预定义的。
exercises: [
{
title: 'Name',
type: 'Weights',
style: ['Strength Building'],
muscleGroups: ['Back', 'Chest'],
difficulty: 'Intermediate'
},
{
title: 'Name',
type: 'Weights',
style: ['Strength Building'],
muscleGroups: ['Back', 'Chest'],
difficulty: 'Intermediate'
}
]
我想将练习与数据/首选项对象匹配。这是一个函数,但是不幸的是我只能对其进行硬编码,并且无法按预期工作。我需要将this.generatorData
与exercises
的数据进行比较-遍历所有练习并找到符合要求的内容。有没有办法使它起作用,并且如果可能的话,如何使该功能自动化?
match() {
let categories = Object.values(this.generatorData)
for(let category of categories) {
if(category.length > 1) {
this.exercises.filter(exercise => {
if(exercise.type === category[0].name || exercise.type === category[1].name || exercise.type === category[2].name) {
if(exercise.difficulty === category[categories.length - 1].name) {
this.matchedExercies.push(exercise)
}
}
})
}
else if(category.length === 1) {
let filtered = this.exercises.filter(exercise => exercise.type === category[0].name)
console.log(filtered)
this.matchedExercies = filtered
}
}
}
这里是codeSandbox。
答案 0 :(得分:1)
所以这只是一个普通的js问题,而不是太多的问题。
假设使用跨过滤器的AND和跨过滤器选择的过滤来完成过滤,这是一个有效的版本(需要对模式进行一些更改)
Foo
更新
看看codesandbox,看来您的商店实际上是在为generatorData提供>>> [a for a in inspect.getmembers(Bar(), lambda at: not(inspect.isroutine(at))) if not(a[0].startswith('__'))]
[('ca1', 'a class attribute in Foo'),
('ca2', 'a class attribute in Bar'),
('ia', 'an instance attribute in Bar')] # note Foo's
# instance attributes are missing
而不是// the values are in an array, to use the `title` some changes may be needed
const generatorData = {
types: [],
style: [],
muscleGroups: [{name:'Back'}],
difficulty: [{name:'Beginner'},{name:'Intermediate'}]
}
const exercises = [
{
title: 'Name',
type: 'Weights',
style: ['Strength Building'],
muscleGroups: ['Toes', 'Chest'],
difficulty: 'Intermediate'
},
{
title: 'Name',
type: 'Weights',
style: ['Strength Building'],
muscleGroups: ['Back', 'Chest'],
difficulty: 'Intermediate'
},
{
title: 'Name',
type: 'Weights',
style: ['Strength Building'],
muscleGroups: ['Back', 'Chest'],
difficulty: 'Effin Hard'
}
]
// I loop over the categories first, removing any that are not needed
const categories = Object.keys(generatorData).map(k => {
// if you want to keep using `title`, this is a good place to do that (val from all titles)
if (generatorData[k].length > 0) return { key: k, val: generatorData[k].map(g => g.name) };;
return false
}).filter(i => i !== false);
let filtered = exercises.filter(e => {
// filter all categories, and compare length of matching filters with the number of filters (enforces AND rule)
return categories.filter(f => {
// if key is missing, assume true
if (e[f.key] === undefined) return true;
// loop through filter values and make sure at leas one matches (OR condition)
return f.val.filter(v => {
// handle string as direct match
if (typeof e === "string") return e[f.key] === v;
// handle array with `includes`
return e[f.key].includes(v)
}).length > 0
}).length === categories.length;
})
console.log(filtered)
代替:
name
它使用:
title
代码已更新为使用difficulty: [
{ title: 'Beginner', ..some properties },
{ title: 'Intermediate', .. }
]
的对象数组
答案 1 :(得分:1)
这对于复杂的选择可能更好。
matchPreferencesWithExercises() {
let categories = this.generatorData;
this.exercises.map(exercise => {
let error = 0;
let matched;
for (let categoryName in categories) {
if (exercise[categoryName]) {
if (typeof exercise[categoryName] === "string") {
!categories[categoryName]
.map(item => item.name)
.includes(exercise[categoryName]) && error++;
} else {
matched = 0;
exercise[categoryName].map(exerciseAttr => {
categories[categoryName].includes(exerciseAttr) && matched++;
});
}
}
}
(error === 0 || matched > 0) && this.matchedExercies.push(exercise);
});
}