I have two objects that I need to combine somehow to achieve a desired output. Here's a toy example.
Let's say that I'm running an experiment about a new mice diet. I gathered 6 mice and fed each of them with a different diet. After several weeks, I weighted all mice and recorded each one's weight. Those weights are given in the following object:
const postExperimentWeights = {
mickey: 20,
minnie: 11,
jerry: 15,
stuart: 33,
gonzales: 17,
pinky: 50,
};
To conclude whether any of the diets was successful, I have another data object, with the target weights that would be considered bad, mediocre, or good, per mouse.
const targetWeights = {
mickey: {
belowIsBad: 15,
aboveIsGood: 22,
},
minnie: {
belowIsBad: 5,
aboveIsGood: 10,
},
jerry: {
belowIsBad: 16,
aboveIsGood: 20,
},
stuart: {
belowIsBad: 30,
aboveIsGood: 40,
},
gonzales: {
belowIsBad: 10,
aboveIsGood: 15,
},
pinky: {
belowIsBad: 60,
aboveIsGood: 100,
},
};
And my desired output is 3 variables, each of which contains an array of names:
const good = ['minnie', 'gonzales']; // those were above their respective `aboveIsGood`
const mediocre = ['mickey', 'stuart']; // were between respective `belowIsBad` & `aboveIsGood`
const bad = ['jerry', 'pinky']; // below respective `belowIsBad`
Is there a fairly simple or elegant way to achieve the desired output? I typically prefer to utilize a functional approach, but regardless would be grateful for any help.
I'd iterate the expirement results using Object.entries() and the simply compare with the target values:
const postExperimentWeights = {
mickey: 20,
minnie: 11,
jerry: 15,
stuart: 33,
gonzales: 17,
pinky: 50,
};
const targetWeights = {
mickey: {
belowIsBad: 15,
aboveIsGood: 22,
},
minnie: {
belowIsBad: 5,
aboveIsGood: 10,
},
jerry: {
belowIsBad: 16,
aboveIsGood: 20,
},
stuart: {
belowIsBad: 30,
aboveIsGood: 40,
},
gonzales: {
belowIsBad: 10,
aboveIsGood: 15,
},
pinky: {
belowIsBad: 60,
aboveIsGood: 100,
},
};
function evaluateResults(input, target) {
const good = [];
const avg = [];
const bad = [];
for(const [key,value] of Object.entries(input)) {
if(value < target[key].belowIsBad) {
bad.push(key);
}else if(value > target[key].aboveIsGood) {
good.push(key);
}else {
avg.push(key);
}
}
console.log("good:", good);
console.log("avg:", avg);
console.log("bad:", bad);
}
evaluateResults(postExperimentWeights,targetWeights);
Another solution using reduce using push instead of concat
const postExperimentWeights = {mickey: 20,minnie: 11,jerry: 15,stuart: 33,gonzales: 17,pinky: 50,};
const targetWeights = { mickey: {belowIsBad: 15,aboveIsGood: 22,},minnie: {belowIsBad: 5,aboveIsGood: 10,},jerry: {belowIsBad: 16,aboveIsGood: 20,},stuart: {belowIsBad: 30,aboveIsGood: 40,},gonzales: {belowIsBad: 10,aboveIsGood: 15,},pinky: {belowIsBad: 60,aboveIsGood: 100,},};
let res = Object.entries(postExperimentWeights).reduce((acc, [mouse,weight]) => {
if (weight > targetWeights[mouse].aboveIsGood) acc.good.push(mouse)
else if (targetWeights[mouse].belowIsBad < weight && weight <targetWeights[mouse].aboveIsGood) acc.mediocre.push(mouse)
else if (targetWeights[mouse].belowIsBad > weight) acc.bad.push(mouse)
return acc
}, {good: [],mediocre: [],bad: []})
console.log(res)
You can use this piece of code in simplest term
const mices = {
mickey: 20,
minnie: 11,
jerry: 15,
stuart: 33,
gonzales: 17,
pinky: 50
};
const targetWeights = {
mickey: {
belowIsBad: 15,
aboveIsGood: 22
},
minnie: {
belowIsBad: 5,
aboveIsGood: 10
},
jerry: {
belowIsBad: 16,
aboveIsGood: 20
},
stuart: {
belowIsBad: 30,
aboveIsGood: 40
},
gonzales: {
belowIsBad: 10,
aboveIsGood: 15
},
pinky: {
belowIsBad: 60,
aboveIsGood: 100
}
};
function findTheWeights(main, target) {
const good = [];
const mediocre = [];
const bad = [];
for (let mice in main) {
const { belowIsBad, aboveIsGood } = target[mice];
main[mice] > aboveIsGood
? good.push(mice)
: main[mice] < belowIsBad
? bad.push(mice)
: mediocre.push(mice);
}
return { good, bad, mediocre };
}
console.log(findTheWeights(mices, targetWeights));