Im using javascript for this. I have an dataset as followings:
var filteredValues = [{
type1 : [ ],
type2 : [{w:86,h:108,l:66}, {w:86,h:109,l:66}],
type3 : [{w:82,h:110,l:73}]
}]
I want to be able to filter this dataset to the nearest item based on the values of h
provided by the user.
Example: if the user provides 105
as h
, the below would happen
type1
will be discarded as nothing is selected there at the moment.105
would match againsth
value oftype2
andtype3
and whichever is closest, would be selected. In this case,{w:86,h:108,l:66}
fromtype2
as105
is closest or equal to109
or110
(fromtype3
) .- the result of the output would be the type name, in this case
type2
Please feel free to correct the question if you see any mistakes. Also if you think changing dataset can make it easier, let me know.
Below are few interesting thread that may be helpful
How to find nearest element in nested array javascript?
Find object in array with closest value
Update:
I tried the following
function getResult(filteredValues, 105){
filteredValues.reduce((acc, obj) =>
Math.abs(y - obj.s) < Math.abs(y - acc.s) ? obj : acc
);
}
Thank you very much in advance.
CodePudding user response:
I've just written this code and it seems to work, but it would need to be tested more (it's bigger but maybe more understandable):
const filteredValues = [
{
type1: [],
type2: [
{ w: 86, h: 108, l: 66 },
{ w: 86, h: 109, l: 66 },
],
type3: [{ w: 82, h: 106, l: 73 }],
},
];
function filter(h) {
const keys = Object.keys(filteredValues[0]);
const values = Object.values(filteredValues[0]);
const length = keys.length;
let tempType = keys[0];
let tempClosestHValue = values[0][0]?.h ?? Infinity;
for (let i = 0; i < length; i ) {
const type = values[i];
const key = keys[i];
if (type.length > 0) {
let closestHValue = Math.abs(type[0].h - h);
for (let y = 0; y < values[i].length; y ) {
let data = values[i][y];
if (Math.abs(data.h - h) < closestHValue) {
closestHValue = data.h;
}
}
if (closestHValue < tempClosestHValue) {
tempClosestHValue = closestHValue;
tempType = key;
}
}
}
return tempType;
}
console.log(filter(105));
which returns "type3", but if you modify the h
property of the third type to 110, you get "type2" as the output.
CodePudding user response:
This solution takes only the object of the given data.
With the entries,
- filter empty arrays
- map the result of reducing the array by taking the absolute delta to get the smallest possible value to the target value.
At the end create a new object from entries.
const
data = { type1: [], type2: [{ w: 86, h: 108, l: 66 }, { w: 86, h: 109, l: 66 }], type3: [{ w: 82, h: 110, l: 73 }] },
height = 105,
result = Object.fromEntries(Object
.entries(data)
.filter(([_, { length }]) => length)
.map(([k, v]) => [k, v.reduce((a, b) => Math.abs(a.h - height) <= Math.abs(b.h - height)
? a
: b
)])
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }