I have an object containing an undefined number of child objects which are associated by numeric values as the object keys. What I need is a way to pass in a numeric number (currency) and get the child object that is the closest to the number I pass into the function.
Example Object structure
{
"32.5": [
{
"key": "value",
"key": "value"
},
{
"key": "value",
"key": "value"
}
],
"34": [
{
"key": "value",
"key": "value"
}
],
"35.5": [
{
"key": "value",
"key": "value"
}
]
}
The keys of the object are strings, so I already figured out I probably somehow have to parse the object keys to a number for comparison but I am completely lost on how to tie it all together.
I declared a function that takes 3 parameters which at the end should return the child object where its key is the closest to my input parameter.
function getNearest(obj, decimalNumber, below_or_above)
when I put in “above” I want to get the closest key where its number value is the next higher, when I put in “below” it would return the next object where its number key is the next smaller.
If I would call getNearest(obj, 33.4, above) it should return the object with the key “34”.
I hope I managed somehow to explain so everyone can understand..
This is the starting point I came up with but I don’t know how to proceed from here
function getNearest(obj, decimalNumber, above_or_below){
const keys = [];
Object.keys(obj).forEach(key =>{
let numericKey = Number(key);
keys.push(numericKey);
})
//store all numeric keys in array to further process later on
}
Advertisement
Answer
- Transform the object into an array of items using Object.entries.
- Loop over the object using Array.prototype.map and convert the string keys to numbers, to perform comparisons correctly.
- Sort the array by the keys using Array.prototype.sort.
- Find the key based on the
pos
argument using Array.prototype.find. - Finally return the value corresponding to the found key.
const
data = { 32.5: [{ key: "32.5" }], 34: [{ key: "34" }], 35.5: [{ key: "35.5" }] },
getKey = (obj, target, pos) =>
Object.entries(obj)
.map(([k, v]) => [Number(k), v])
.sort(([a], [b]) => a - b)
.find(([k], i, a) =>
pos === "above"
? k >= target
: k <= target && (a[i + 1]?.[0] > target || i === a.length - 1)
)?.[1];
console.log(getKey(data, 33, "above")); // [{ key: "34" }]
console.log(getKey(data, 33, "below")); // [{ key: "32.5" }]
console.log(getKey(data, 37, "above")); // undefined
console.log(getKey(data, 30, "below")); // undefined
Table for reference:
target | below | above |
---|---|---|
0 |
undefined |
[{ key: '32.5' }] |
31.4 |
undefined |
[{ key: '32.5' }] |
32.5 |
[{ key: '32.5' }] |
[{ key: '34' }] |
32.8 |
[{ key: '32.5' }] |
[{ key: '34' }] |
33.4 |
[{ key: '32.5' }] |
[{ key: '34' }] |
34 |
[{ key: '34' }] |
[{ key: '34' }] |
35.1 |
[{ key: '34' }] |
[{ key: '35.5' }] |
35.5 |
[{ key: '35.5' }] |
[{ key: '35.5' }] |
50 |
[{ key: '35.5' }] |
undefined |