根据选择的偏好匹配数据

时间:2018-12-13 17:25:25

标签: javascript vue.js

我正在尝试使用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.generatorDataexercises的数据进行比较-遍历所有练习并找到符合要求的内容。有没有办法使它起作用,并且如果可能的话,如何使该功能自动化?

 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

2 个答案:

答案 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);
      });
    }

https://codesandbox.io/s/qo74o6z9