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 |