这是我的jsfiddle:https://jsfiddle.net/kpam8g79/9/
我有一个函数findCommon:
function findCommon(ar1, ar2, ar3)
{
// Initialize starting indexes for ar1[], ar2[] and ar3[]
let i = 0, j = 0, k = 0;
// Iterate through three arrays while all arrays have elements
while (i < ar1.length && j < ar2.length && k < ar3.length)
{
// If x = y and y = z, print any of them and move ahead
// in all arrays
if (ar1[i] == ar2[j] && ar2[j] == ar3[k])
{ console.log(ar1[i]+" "); i++; j++; k++; }
// x < y
else if (ar1[i] < ar2[j])
i++;
// y < z
else if (ar2[j] < ar3[k])
j++;
// We reach here when x > y and z < y, i.e., z is smallest
else
k++;
}
}
我的数据集如下:
const ar1 = [1, 2, 3, 6, 8];
但是当我的数据集是一个对象数组时
const oAr1 = ar1.map(v => ({value: v, display: `value ${v}`}));
我仍然想获得共同的价值观。
我可以将oAr1映射到ar1并调用findCommon函数,但这可能不起作用。我还可以修改findCommon函数以采用对象数组而不是数字数组,但是我想重用findCommon。我想知道是否可以使用函数式编程来以某种方式组合两个函数,以便可以重用findCommon。
我想知道如何做到这一点...
答案 0 :(得分:3)
您可以在findCommon
上添加一个可选参数,默认为x => x
。
这使您可以传递一个函数,该函数描述查找要比较的值所需的逻辑。
const ar1 = [1, 2, 3, 6, 8];
const ar2 = [1, 5, 6, 9];
const ar3 = [1, 4, 5, 6];
const oAr1 = ar1.map(v => ({value: v, display: `value ${v}`}));
const oAr2 = ar2.map(v => ({value: v, display: `value ${v}`}));
const oAr3 = ar3.map(v => ({value: v, display: `value ${v}`}));
findCommon(ar1, ar2, ar3);
findCommon(oAr1, oAr2, oAr3, o => o.value);
function findCommon(ar1, ar2, ar3, getValue = x => x)
{
// Initialize starting indexes for ar1[], ar2[] and ar3[]
let i = 0, j = 0, k = 0;
// Iterate through three arrays while all arrays have elements
while (i < ar1.length && j < ar2.length && k < ar3.length)
{
var x1 = getValue(ar1[i]);
var x2 = getValue(ar2[j]);
var x3 = getValue(ar3[k]);
// If x = y and y = z, print any of them and move ahead
// in all arrays
if (x1 === x2 && x2 === x3)
{ console.log(x1, ar1[i]); i++; j++; k++; }
// x < y
else if (x1 < x2)
i++;
// y < z
else if (x2 < x3)
j++;
// We reach here when x > y and z < y, i.e., z is smallest
else
k++;
}
}
答案 1 :(得分:1)
一种方法是添加一个比较函数(例如Java的Comparator<>
)作为参数。
// default comparator
function defCompare(x, y) { return x > y ? 1 : x < y ? -1 : 0; }
function findCommon(ar1, ar2, ar3, cmp = defCompare)
{
let i = 0, j = 0, k = 0;
while (i < ar1.length && j < ar2.length && k < ar3.length)
{
// call the custom comparator
let c1 = cmp(ar1[i], ar2[j]);
let c2 = cmp(ar2[j], ar3[k]);
if (c1 == 0 && c2 == 0)
{ console.log(ar1[i] + " "); i++; j++; k++; }
else if (c1 == -1)
i++;
else if (c2 == -1)
j++;
else
k++;
}
}
// custom comparator for the objects
function customCompare(x, y) { return defCompare(x.value, y.value); }
const common2 = findCommon(oAr1, oAr2, oAr3, customCompare);
这正常工作...除了console.log
本身打印对象之外。一种解决方法是将比较器更改为“值提取器”函数,该函数返回要与之进行比较的数量:
// default: just return itself
function defValue(x) { return x; }
function findCommon(ar1, ar2, ar3, val = defValue)
{
let i = 0, j = 0, k = 0;
while (i < ar1.length && j < ar2.length && k < ar3.length)
{
// call the value extractor
let v1 = val(ar1[i]);
let v2 = val(ar2[j]);
let v3 = val(ar3[k]);
if (v1 == v2 && v2 == v3)
{ console.log(v1 + " "); i++; j++; k++; }
else if (v1 < v2)
i++;
else if (v2 < v3)
j++;
else
k++;
}
}
// custom extractor for objects
function customValue(x) { return x.value; }
const common2 = findCommon(oAr1, oAr2, oAr3, customValue);
对于您的示例,这将按预期打印2 8
。