I have an array of objects with a name and a value that looks like this (sorted by values):
var array = [
{ Name: "F", Value: 320 },
{ Name: "E", Value: 321 },
{ Name: "C", Value: 340 },
{ Name: "G", Value: 340 },
{ Name: "A", Value: 400 },
{ Name: "D", Value: 403 },
{ Name: "B", Value: 404 }
]
I want to combine objects with the same value plus a tolerance. Grouping can be done like this:
var groupedArray = Object.groupBy(array, e => e.Value ); // Is it possible to add a tolerance factor here?
This creates groups that have exactly the same values. But what I actually want is a grouping with a certain tolerance. So, if values are just slightly larger than the previous value, they should still be included in the group. The result could then look like this:
{
320: [{
Name: "F",
Value: 320
}, {
Name: "E",
Value: 321
}],
340: [{
Name: "C",
Value: 340
}, {
Name: "G",
Value: 340
}],
400: [{
Name: "A",
Value: 400
}, {
Name: "D",
Value: 403
}, {
Name: "B",
Value: 404
}]
}
... so all values with a tolerance of, for example, +5 are in one group. Is it possible to add such a tolerance factor?
You could reduce the sorted array by having a look to the difference of each value and predecessor and keep the group if the difference is in a wanted delta/tolerance.
Finally build entries for a later object.
const
tolerance = 5,
array = [{ Name: "F", Value: 320 }, { Name: "E", Value: 321 }, { Name: "C", Value: 340 }, { Name: "G", Value: 340 }, { Name: "A", Value: 400 }, { Name: "D", Value: 403 }, { Name: "B", Value: 404 }],
result = Object.fromEntries(array
.reduce((r, o, i, a) => {
if (!i || o.Value - a[i - 1].Value > tolerance) r.push([o]);
else r.at(-1).push(o);
return r;
}, [])
.map(a => [a[0].Value, a])
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }