Tyler Williams
Tyler Williams

Reputation: 11

Find object in an array of object with the closest value to a predetermined number

I have a total which will be a number and will change throughout my code and I need to find the closest value in a array of numbers and return the index in the result which should be Mia Vobos.

I'm trying to match two people whose sum (sum relates to the values added up in the questions they were asked) equals each other or find someone who is closest.

Used .map to return whats up above except a sum of scores instead of individual ones.

I expected the output to be result[2] which is (Mia Vobos) because her score of three is closest to the total of 2, but I get:

element.reduce is not a function

// My array of people and their scores
var peopleArray = [
    {
        name: "Hector Valdes",
        photo: "",
        scores: ["5", "1", "4", "4", "5", "1", "2", "5", "4", "1"]
    }, {
        name: "Tyler Williams",
        photo: "",
        scores: ["5", "1", "4", "4", "5", "2", "2", "5", "4", "1"]
    }, {
        name: "Mia Vobos",
        photo: "",
        scores: ["2", "1"]
    }
];
 
var total = 2
const result = peopleArray.map((value) => {
    return {
        name: value.name,
        score: value.scores.reduce((total, score) => total + Number(score), 0)
    }
});
console.log(result);

for (let i = 0; i < result.length; i++) {
    const element = result[i].score;
    if (total == result[i].score) {
        console.log(result[i])
    } else {
        var closest = element.reduce(function(prev, curr) {
            return (Math.abs(curr - total) < Math.abs(prev - total) ? curr : total);
        });
    }
}
console.log(closest);

Upvotes: 0

Views: 66

Answers (2)

Carsten Massmann
Carsten Massmann

Reputation: 28196

Sure, learning a modern programming language like Typescript is advantageous but not really necessary if you want to solve the problem at hand. It can be done via the following short JavaScript function.

peopleArray = [
{
    name: "Hector Valdes",
    photo: "",
    scores: ["5", "1", "4", "4", "5", "1", "2", "5", "4", "1"]
}, {
    name: "Tyler Williams",
    photo: "",
    scores: ["5", "1", "4", "4", "5", "2", "2", "5", "4", "1"]
}, {
    name: "Mia Vobos",
    photo: "",
    scores: ["2", "1"]
}
];

function getClosestScoreTo(pa,target=0){
 return pa.reduce(([min,mel],el)=>{
 const tot=Math.abs(target-el.scores.reduce((a,c)=>+a+(+c)));
 return tot<min?[tot,el]:[min,mel];
}, [Number.MAX_VALUE])[1]
}

console.log(getClosestScoreTo(peopleArray,2))

 

The function getClosestScoreTo(pa,target) uses the Array method .reduce() on two levels: on the inner level the total score for each pa-element is established and in the outer level the element that is closest to the given target value is selected.

Upvotes: 0

Michael Alvarez
Michael Alvarez

Reputation: 11

First, element.reduce will not work because element is not an array. See mdn docs for reduce: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

Secondly, here's a start/general outline. Be aware that this is probably more advanced than you are used to, but I left it open for you to edit and added my comments there. Full disclosure: You probably don't want to use typescript if it's for a class that doesn't use typescript.

https://codepen.io/anon/pen/MMKEvg?editors=1012

const peopleArray = [
{
    name: "Hector Valdes",
    photo: "",
    scores: [
        "5", "1",
        "4", "4",
        "5", "1",
        "2", "5",
        "4", "1"
    ]
}, {
    name: "Tyler Williams",
    photo: "",
    scores: [
        "5", "1",
        "4", "4",
        "5", "2",
        "2", "5",
        "4", "1"
    ]
}, {
    name: "Mia Vobos",
    photo: "",
    scores: [
        "2", "1",

    ]
}

]

function getClosestMatch(total:number) {

 // First add the totals to each person
     peopleArray = peopleArray.map((person) => {
       person = {
         ...person,// This is called destructuring (look it up)
          total: // Insert your code here, and make sure to do parseInt(stringNumberValue, 10)
       }
       return person;
     })

    // Then just get the closest match
    var closestMatchingPerson = peopleArray.reduce(function(prev, curr) {
        return // Calculate the difference here, and return either previous or current
    });

  return closestMatchingPerson;

}

getClosestMatch(31);

Additional comments: Did you notice the ': number' part in the function getClosestMatch? You can remove that part if you're not using typescript. I do recommend learning typescript if you want to be a frontend / javascript engineer though!

Upvotes: 1

Related Questions