Reputation: 815
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
}
Upvotes: 1
Views: 435
Reputation: 386530
You could
value below above
------- ------- -------
0 undef 32.5
31.4 undef 32.5
32.5 32.5 34
32.8 32.5 34
33.4 32.5 34
34 34 34
35.1 34 35.5
35.5 35.5 35.5
50 35.5 undef
isAbove false true
const
getKey = (object, value, isAbove) => Object
.keys(object)
.map(Number)
.sort((a, b) => a - b)
.find((v, i, a) => isAbove
? v >= value
: v <= value && (a[i + 1] > value || i + 1 === a.length)
),
data = { 32.5: [{}], 34: [{}], 35.5: [{}] };
console.log('below');
console.log(getKey(data, 0)); // 32.3
console.log(getKey(data, 31.4)); // 32.3
console.log(getKey(data, 32.5)); // 32.3
console.log(getKey(data, 32.8)); // 32.3
console.log(getKey(data, 33.4)); // 34
console.log(getKey(data, 34)); // 34
console.log(getKey(data, 35.1)); // 35.5
console.log(getKey(data, 35.5)); // 35.5
console.log(getKey(data, 100)); // 35.5
console.log('above');
console.log(getKey(data, 0, true)); // 32.3
console.log(getKey(data, 31.4, true)); // 32.3
console.log(getKey(data, 32.5, true)); // 32.3
console.log(getKey(data, 32.8, true)); // 32.3
console.log(getKey(data, 33.4, true)); // 34
console.log(getKey(data, 34, true)); // 34
console.log(getKey(data, 35.1, true)); // 35.5
console.log(getKey(data, 35.5, true)); // 35.5
console.log(getKey(data, 100, true)); // 35.5
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 8158
pos
argument using Array.prototype.find.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 |
Upvotes: 1