Tailoring information to fit selected preferences

Currently working on developing a fitness app with Vue, aiming to create personalized workout routines based on user preferences. Users can choose specific options and generate a workout plan by clicking a button. The collected data is stored as an object of arrays, where each array contains objects representing the selected options (e.g., workout duration, difficulty level, preferred exercises).

this.generatorData = {
  types: [],
  style: [],
  muscleGroups: [],
  difficulty: [
    { title: 'Beginner', ..some properties },
    { title: 'Intermediate', .. }
  ]
}

In addition, I have a list of predefined exercises that share similar properties as the generated objects.

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'
  }
]

The goal is to match exercises with the user's preferences specified in the data object. Trying to achieve this using a function, but it currently involves hardcoding and does not meet the desired expectations. Want to automate the process of comparing the data from this.generatorData with the exercises - iterate through all exercises and identify those that meet the criteria. Is there a way to enhance this functionality and make the function more efficient?

 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
         }
     }
 }

Access the codeSandbox here.

Answer №1

It seems like the issue at hand involves plain JavaScript rather than Vue.

If the filtering is based on AND logic for filters and OR logic for filter choices, a functional version is provided below (with adjustments required in the schema).

// To utilize the `title`, some modifications may be necessary since values are in an array
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'
  }
]

const categories = Object.keys(generatorData).map(k => {
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 => {
  return categories.filter(f => {
    if (e[f.key] === undefined) return true;
    return f.val.filter(v => {
      if (typeof e === "string") return e[f.key] === v;
      return e[f.key].includes(v)
    }).length > 0
  }).length === categories.length;
})

console.log(filtered)


Update:

After reviewing the codesandbox, it appears that your store provides generatorData with name instead of title

Instead of:

difficulty: [
  { title: 'Beginner', ..some properties },
  { title: 'Intermediate', .. }
]

It uses:

difficulty: [
  { name: 'Beginner'},
  { name: 'Intermediate'}
]

The code has been updated to accommodate an array of objects with name

Answer №2

This function is ideal for handling complex selections.

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

Link to example on CodeSandbox

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using Javascript and jQuery to modify the element's ID

I've been trying to automate the loading process of articles on my website, but I'm having trouble with the line $(tytul).html(data);. Is there a way to get this working correctly? var numboart = 3; $(document).ready(function(){ for(i=0;i& ...

The issue with the NextJS Layout component is that it is failing to display the page content, with an error message indicating that objects cannot be used

I am embarking on my first project using Next JS and after watching several tutorial videos, I find the Layout component to be a perfect fit for my project! However, I am encountering an issue where the page content does not display. The Menu and Footer a ...

Adding a method to a node module by hand

Working with my website, I've incorporated the material-ui package, but the version available on npm is outdated compared to the latest one on Github. To reflect these updates, I manually inserted this line of code into their Theme Manager class: set ...

Exploring Data in Angular 2: Examining Individual Records

I am currently learning Angular and facing some challenges in structuring my questions regarding what I want to achieve, but here is my query. Within a component, I am retrieving a single user record from a service. My goal is to display this user's ...

What is the most efficient and hygienic method for storing text content in JavaScript/DOM?

Typically, I encounter version 1 in most cases. However, some of the open source projects I am involved with utilize version 2, and I have also utilized version 3 previously. Does anyone have a more sophisticated solution that is possibly more scalable? V ...

Iterate through an ajax function by employing promises

I have recently delved into the world of es6-promises and I'm struggling to fully grasp its concepts. In my project, I am attempting to retrieve data through an ajax call and keep looping until all data is fetched (essentially pagination). Below is t ...

Encountering an issue with WebDriver in the realm of JavaScript

I am struggling to use JavaScript to locate specific controls and send values to them. One example is changing the text in a textbox with the ID "ID" to "123456". Below is the code I tried: ((IJavaScriptExecutor)driver).ExecuteScript("document.getElement ...

Using Regex in JavaScript to split a string based on a saved pattern

I have a specific sentence to work with: var sentence="example of+a+string"; My goal is to split the string by the + symbol only when it occurs after the word "of". When attempting this with the code: sentence.split(/of(\+)/) The result splits th ...

What is the procedure for submitting all checkbox values through Google Apps Script?

My web app created using Google Apps Script can generate a custom table of data for users to select for calculations. I use Google Sheets to populate the table with values and checkboxes, but note that the table size may vary depending on the user. <fo ...

Changing $scope within an AngularJS service

I am currently working on an application that utilizes the Gmaps API for geolocalization. One of the challenges I faced was adding new markers based on user events. To address this, I created a service that listens to map events and adds markers when click ...

Deleting a hyperlink within a content-editable area

Presently, I am in the process of working on a straightforward project where users can format text using contenteditable. I have successfully implemented a feature that allows users to add hyperlinks to selected text by clicking on the "Create Link" button ...

What is the best way to retrieve data from the server for individual div elements?

Utilizing Laravel and JQuery to render the HTML is my current approach. <div id="div1">0</div> <div id="div2">0</div> <div id="div3">0</div> Each instance of 0 within the divs needs to be s ...

Angular 2's Multi-select dropdown feature allows users to select multiple options

Recently, I encountered an issue with customizing CSS for angular2-multiselect-dropdown. I found the solution in this link: https://www.npmjs.com/package/angular2-multiselect-dropdown. I have included my code below. Any assistance in resolving this matter ...

Encountering a problem with the persistent JavaScript script

I have implemented a plugin/code from on my website: Upon visiting my website and scrolling down, you will notice that the right hand sidebar also scrolls seamlessly. However, when at the top of the screen, clicking on any links becomes impossible unless ...

Executing a function from another reducer using React and redux

My application consists of two main components: the Market and the Status. The Status component manages the user's money, while the Market component contains buttons for purchasing items. My goal is to decrement the user's money when a button in ...

Error: the function is not defined, therefore the variable is being passed

I'm attempting to pass a variable in the URL in order to automatically check a radio button on a different page depending on which link is clicked. However, I keep encountering an "Uncaught ReferenceError: radio_onload is not defined" error. Could th ...

Placing a cookie using nookies within the Next.js API directory

I'm currently facing an issue while trying to use the nookies npm package to set a cookie within the Next.js api folder. I've successfully set up a cookie using the same code with nookies before, but for some reason, it's not working in this ...

Establishing a constant for a JavaScript class method

Although this question may seem basic, I am struggling to grasp how this code works and felt the need to seek clarification here. Take a look at this example of a simple React component: const title = React.createElement( 'h1', {id: &apo ...

node js retrieves information from the request body

Hey there! I'm diving into the world of Node.js and JavaScript, but I've hit a roadblock. I'm trying to fetch data from a URL using node-fetch, then parse it as JSON. However, I keep running into the issue of getting 'undefined' in ...

Bug in canvas rendering for Chrome versions 94 and 95

The Canvas drawing functionality in the Chrome browser seems to have some visible bugs. Here's an example of code that demonstrates this issue: const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d&apo ...