Нужны некоторые идеи о том, как использовать функциональное программирование в JavaScript, чтобы повторно использовать функцию - PullRequest
0 голосов
/ 11 сентября 2018

Вот мой 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.

Интересно, как это можно сделать ...

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Вы можете добавить дополнительный параметр к вашему 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++;
    }
}
0 голосов
/ 11 сентября 2018

Один из способов - добавить функцию сравнения (например, 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 как положено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...