Reputation: 65
I have two arrays of numbers a and b, I want to find closest pair of numbers from this array. But I am stuck inside the reducer, with given match to
.
Expected output is
[
{
"dif": 1,
"val": 3,
"to": 4
},
{
"dif": 2,
"val": 3,
"to": 5
},
{
"dif": 2,
"val": 8,
"to": 6
}
]
const a = [1,2,3,8]
, b = [4,5,6]
const result = b.map(to => {
return a
.map(v => {return {val:v}})
.reduce((prev, curr) => {
return Math.abs(curr.val - to) < Math.abs(prev.val - to) ? {dif:Math.abs(prev.val - to), val:curr.val, to} : {dif: Math.abs(prev.val - to), val:prev.val, to}
});
})
console.log(result)
Upvotes: 0
Views: 94
Reputation: 386520
You could generate the cartesian product and sort by difference.
var a = [1, 2, 3, 8],
b = [4, 5, 6],
result = a
.reduce((r, c) => r.concat(b.map(d => ({ dif: Math.abs(c - d), val: c, to: d }))), [])
.sort((a, b) => a.dif - b.dif);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 5309
another choice:
const a = [1, 2, 3, 8],
b = [4, 5, 6];
const result = b.map(v => {
return a.reduce((re, value) => {
let updateRule = re.val === undefined || (re.val !== undefined && Math.abs(value - re.to)) < re.dif;
return updateRule ? { val: value, dif: Math.abs(value - re.to), to: v } : re;
}, { to: v });
});
console.log(result);
Upvotes: 0
Reputation: 1105
There is one correction in your code. {dif:Math.abs(prev - to), val:curr.val, to}
should be {dif:Math.abs(curr.val - to), val:curr.val, to}
const a = [1,2,3,8]
, b = [4,5,6]
const result = b.map(to => {
return a
.map(v => {return {val:v}})
.reduce((prev, curr) => {
return Math.abs(curr.val - to) < Math.abs(prev.val - to) ? {dif:Math.abs(curr.val - to), val:curr.val, to} : {dif: Math.abs(prev.val - to), val:prev.val, to}
});
})
console.log(result)
Upvotes: 1