Let's start with an example.
I have a list of fruits and it's nutritions stored in JS objects. Then I get a vegetable which is not in the list but has same types of values as the keys in the fruits object.
How can I get the closest fruit from the fruit object to the vegetable given vegetable if 1) the nutrition values (sugar,salt,...) has same values (sugar = salt) 2) the nutrition values (sugar,salt,...) have different values (sugar > salt, so basicly check only for sugar). I know that's not a good explanation, but let's check the example below.
let fruits = {
apple:{
sugar:12,
salt:5
},
banana:{
sugar:13,
salt:3
},
}
let cucumber = {
sugar:12,
salt:3
}
let closestFruitToCucumber = closest(cucumber, fruits)
// apple (if checking only sugar)
// banana (if both sugar and salt are valued the same)
function closest(vegetable,fruitList){
// here is the part which I am looking for.
}
I can post the code, which I have tried. There were plenty of them but none of them worked at all.
Following up on my comment:
I guess that you want to calculate the absolute difference for every matching key in the objects, and then sum these differences for each comparison, finally selecting the comparison with the lowest sum.
I'd use a functional approach so that you can refine your result by a query parameter (property key(s)). This approach will continue to work even if the two objects don't share the same property keys, and it will also allow you to easily refactor if the standard property keys change in your data:
const defaultKeys = ['salt', 'sugar'];
function getSimilarityScore (a, b, keys = defaultKeys) {
let score = 0;
for (const key of keys) score += Math.abs((a[key] ?? 0) - (b[key] ?? 0));
return score;
}
function closest (objList, obj, keys = defaultKeys) {
let minScore = Number.POSITIVE_INFINITY;
let result;
for (const o of Object.values(objList)) {
const score = getSimilarityScore(obj, o, keys);
if (score >= minScore) continue;
minScore = score;
result = o;
}
return result;
}
const fruits = {
apple: {
salt: 5,
sugar: 12,
},
banana: {
salt: 3,
sugar: 13,
},
};
const cucumber = {
salt: 3,
sugar: 12,
};
const closestToCucumber = closest(fruits, cucumber);
const closestToCucumberBySalt = closest(fruits, cucumber, ['salt']);
const closestToCucumberBySugar = closest(fruits, cucumber, ['sugar']);
console.log(closestToCucumber === fruits.banana); // true
console.log(closestToCucumberBySalt === fruits.banana); // true
console.log(closestToCucumberBySugar === fruits.apple); // true