Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Alter leftJoin function from an a exact match to contains JavaScript/Google app script

I have the left join function, which combines two arrays of different dimensions by exact matching on columns.

function test() {
  let a =[
          ['aH1','aH2','aH3','aH4'],   
          ['a','B','c','d'],
          ['x','R','l','a'],
          ['t','R','g','m'],
          ['t','A','g','m']
         ];

  let b =[
          ['bH1','bH2','bH3'], 
          ['A','ZZ','XX'],
          ['R','YY','RR'],
          ['t','GG','QQ']
         ];

  const result = leftJoin(a, b, "aH2", "bH1")   
  console.log(result)
  
Which gives:
  result = [
            [ 'aH1', 'aH2', 'aH3', 'aH4', 'bH2', 'bH3' ],
            [ 'a', 'B', 'c', 'd', '', '' ],
            [ 'x', 'R', 'l', 'a', 'YY', 'RR' ],
            [ 't', 'R', 'g', 'm', 'YY', 'RR' ],
            [ 't', 'A', 'g', 'm', 'ZZ', 'XX' ] 
           ]
           
}

But what if the matching column of array b now has strings that contain the value to match on. 'H|A|1|L' contain A

let b =[
        ['bH1','bH2','bH3'], 
        ['H|A|1|L','ZZ','XX'],
        ['|D|K|R','YY','RR'],
        ['t|S|G','GG','QQ']
       ];

How to alter leftJoin to do this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I am guessing it is done here

const temp = b.slice(1).reduce((r, items, i) => (r[items[bIndex]] = items, r), {});

But I do not understand reduce enough to get the correct solution

Matching Function:
(sorry, but I do not recall where I found this)

function leftJoin(a, b, akey, bkey) {
    akey = akey.toLowerCase();
    bkey = bkey.toLowerCase();
  
    const without = ([...array], index) => (array.splice(index, 1), array);
    const aIndex = a[0].findIndex(s => s.toLowerCase() === akey);
    const bIndex = b[0].findIndex(s => s.toLowerCase() === bkey);
    const temp   = b.slice(1).reduce((r, items, i) => (r[items[bIndex]] = items, r), {});
        
    return a.map((a, i) => [
        ...a,
        ...without(
                  i
                  ? temp[a[aIndex]] || Array(b[0].length).fill('')
                  : b[0],
                  bIndex
        )
    ]);
}

>Solution :

You could split the string and assign the value to each splitted value.

items[bIndex].split('|').forEach(key => r[key] = items);
function leftJoin(a, b, akey, bkey) {
    akey = akey.toLowerCase();
    bkey = bkey.toLowerCase();

    const without = ([...array], index) => (array.splice(index, 1), array);
    const aIndex = a[0].findIndex(s => s.toLowerCase() === akey);
    const bIndex = b[0].findIndex(s => s.toLowerCase() === bkey);
    const temp = b.slice(1).reduce((r, items, i) => {
          items[bIndex].split('|').forEach(key => r[key] = items);
          return r;        
        }, {});

    return a.map((a, i) => [
        ...a,
        ...without(i
            ? temp[a[aIndex]] || Array(b[0].length).fill('')
            : b[0],
          bIndex
        )
    ]);
}


function test() {
  let a = [
    ['aH1', 'aH2', 'aH3', 'aH4'],
    ['a', 'B', 'c', 'd'],
    ['x', 'R', 'l', 'a'],
    ['t', 'R', 'g', 'm'],
    ['t', 'A', 'g', 'm']
  ];

  let b = [
    ['bH1', 'bH2', 'bH3'],
    ['H|A|1|L', 'ZZ', 'XX'],
    ['|D|K|R', 'YY', 'RR'],
    ['t|S|G', 'GG', 'QQ']
  ];

  const result = leftJoin(a, b, "aH2", "bH1")
  result.forEach(a => console.log(...a));
}

test();
.as-console-wrapper { max-height: 100% !important; top: 0; }
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading