Gabriel Porcher
Gabriel Porcher

Reputation: 55

Select a single object in a map Javascript

I'll start it apologizing for my English ^^

I have this code: code

data: function() {
    return {
        sabor: 0,
        cor: 0,
        teor: 0,
        beers: []
    }
},
methods: {
    
    findOne(){
        var menor = 150;
        var selecionadas = [];
        console.log(this.sabor, this.cor, this.teor)
        var goal = this.sabor + this.cor + this.teor
        console.log(`Goal: ${goal}`)

        this.beers.map( beer => {
            var score = beer.srm + beer.ibu + beer.alcohol
            console.log(`Beer score: ${score}`)
            var choose = Math.abs(goal - score)
            console.log(`Difference: ${choose}`)
            
            if(choose < menor){
                menor = choose
                selecionadas.push(beer)
            }
            
        })
        console.log(`Smallest difference: ${menor}`)
        console.log(`selected: ${selecionadas}`)
    },

As you can see, I have an array of beers. Each beer have some data, such as alcohol, ibu and srm. The user will choose an amount of each of those specifications (by HTML) and I want to find the most similar drink.

I defined a variable goal, which is the sum of those 3 attributes. Then, inside of an Map, I add the beer attributes, and compare with the goal. The beer with smallest difference between the beer score and goal, should be the beer that our user is searching, but that is my problem.

I was trying to start an empty array, and pushing it with beers with the smaller difference (to goal), but this way it give me and array with Object object.

My question is, what can I do to, in 78 and 79 lines, SELECT the perfect beer (with smallest difference), to return to my user?

Upvotes: 1

Views: 507

Answers (1)

Itamar
Itamar

Reputation: 1634

Lets try to answer your questions.

I was trying to start an empty array, and pushing it with beers with the smaller difference (to goal), but this way it give me and array with Object object.

This purely happens because you are printing it as string.
See:

data = {
    sabor: 1,
    cor: 2,
    teor: 4,
    beers: [
      {srm: 1, ibu:1, alcohol:0},
      {srm: 1, ibu:1, alcohol:1},
      {srm: 1, ibu:1, alcohol:2},
      {srm: 2, ibu:1, alcohol:2},
      {srm: 2, ibu:2, alcohol:2},
      ]
}

function findOne(){
    var menor = 150;
    var selecionadas = [];
    var goal = data.sabor + data.cor + data.teor

    for (const beer of data.beers) {
        var score = beer.srm + beer.ibu + beer.alcohol
        var choose = Math.abs(goal - score)
        
        if(choose < menor){
            menor = choose
            selecionadas.push(beer)
        }
        
    }
    

   
    console.log(`selected:`, selecionadas) // <- instead of `selected: ${selecionadas}`
}

findOne()

I am not sure i am down to your second question, but, assuming you are searching for the closest scored beer you can use reduce

See:

data = {
    sabor: 1,
    cor: 2,
    teor: 4,
    beers: [
      {srm: 1, ibu:1, alcohol:0},
      {srm: 1, ibu:1, alcohol:1},
      {srm: 1, ibu:1, alcohol:2},
      {srm: 2, ibu:1, alcohol:2},
      {srm: 2, ibu:2, alcohol:2},
      ]
}

function findOne(){
    var menor = 150;
    var selecionadas = [];
    var goal = data.sabor + data.cor + data.teor
 
    const selectedBeer = data.beers.reduce((ret, beer) => {
      const score = beer.srm + beer.ibu + beer.alcohol
      const choose = Math.abs(goal - score)
      if (!ret) {
        return {...beer, similarity: choose};
      } 
      else if(!Object.hasOwnProperty(ret, 'similarity') || ret.similarity > choose) {
        return {...beer, similarity: choose};
      }
      return ret;
    });

    console.log(`selected:`, selectedBeer)

}

findOne()

Upvotes: 1

Related Questions