0

Arrays -

const source = [1, 1, 1, 3, 4];
const target = [1, 2, 4, 5, 6];

Empty arrays -

const matches1 = [];
const matches2 = [];
const unmatches1 = [];

Loop -

for (const line of source) {
  const line2Match = target.find((line2) => {
    const isMatch = line === line2;
    return isMatch;
  });

  if (line2Match) {
    matches1.push(
      line
    );
    matches2.push(line2Match);
  } else {
    unmatches1.push(line);
  }
}

This is the output right now -

[ 1, 1, 1, 4 ] ​​​​​at ​​​​​​​​matches1​​​

[ 3 ] ​​​​​at ​​​​​​​​unmatches1​​​

[ 1, 1, 1, 4 ] ​​​​​at ​​​​​​​​matches2​​​

The desired output -

[ 1, 4 ] ​​​​​at ​​​​​​​​matches1​​​

[ 1, 1, 3 ] ​​​​​at ​​​​​​​​unmatches1​​​

[ 1, 4 ] ​​​​​at ​​​​​​​​matches2​​​

What I would like to add is when source has a match with target, the value will be deleted from the target array, how can I achive that?

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
heyheyhey2
  • 29
  • 5
  • Does this answer your question? [How to get the difference between two arrays in JavaScript?](https://stackoverflow.com/questions/1187518/how-to-get-the-difference-between-two-arrays-in-javascript) – pilchard Jan 27 '22 at 11:43
  • once again. what is the difference between `matches1` and `matches2`? – Nina Scholz Jan 27 '22 at 11:47
  • @pilchard ty, but no. I don't need to get the difference, I need to remove a value from target array if he found a match – heyheyhey2 Jan 27 '22 at 11:48
  • @NinaScholz On the real arrays they will have different values. Is my question clear? – heyheyhey2 Jan 27 '22 at 11:49
  • no. please use an example which makes the difference clear. – Nina Scholz Jan 27 '22 at 11:51
  • This is an XY Question. The linked duplicate offers solutions for intersection, difference and symetric difference, which covers your needs. – pilchard Jan 27 '22 at 11:54

3 Answers3

-1

Just for matches1: (similar for matches2)

const source = [1, 1, 1, 3, 4];
const target = [1, 2, 4, 5, 6];

let matches1 = source.reduce((res, curr)  => {
    if (target.includes(curr) && !res.includes(curr)) {
        res.push(curr);
    }
    return res;
}, []
);

console.log(matches1)
//[1,4]

For unmatches1:

let unmatches1 = source.reduce((res, curr)  => {
    if ((target.includes(curr) && res[0].includes(curr)) || !target.includes(curr)) {    
        res[1].push(curr);
    }
    if (target.includes(curr)) {
        res[0].push(curr)
    }
    return res;
}, [[],[]]
)[1]

console.log(unmatches1)
//[1,1,3]

To achieve the unmatches2 result [2,5,6] - just replace source and target at the input, or at the code, or extend the code tho have both outputs. It's simple.

Cadet
  • 376
  • 1
  • 9
  • The OP actually wants to know how, in addition to what the OP already has accomplished, an `unmatches2` like calculation of e.g. `[2, 5, 6]` can be achieved. – Peter Seliger Jan 27 '22 at 17:08
  • I didn't really understand the comment. Please be more clear. My solution provides an expected output on provided input, that was not achieved by the code provided in the question. It was a matter of the question. Aha, specifically, to get [2,5,6] just replace source and target - or as input, or in the code. It's simple. – Cadet Jan 27 '22 at 17:19
  • BTW the additional requirement of doing this by one task was added much later. It's the wrong way to add such significant editing a few hours after opening the question. – Cadet Jan 27 '22 at 17:51
  • The OP was very specific about what the OP wants to achieve with the provided source code ... _""What I would **like to add** is when **source has a match with target**, the **value will be deleted from the target array**, how can I achive that?""_ ... which of cause can be translated to ... _How to collect the intersection and both complements of two arrays within one task?_ – Peter Seliger Jan 27 '22 at 18:10
  • Well, there are actually 2 not-related questions: The first one said "This is the output right now - <...>The desired output -<...>", probably meaning that the algorithm in the question doesn't work as desired. As soon as desired output didn't match the actual - I provided a solution that works as "desired". The second question mentioned by you could be easily solved based on the solution I provided to the first one. Need to work a little bit :) Well, the arguing becomes boring. Good luck :) – Cadet Jan 27 '22 at 20:04
-1

The OP ...

"What I would like to add is when source has a match with target, the value will be deleted from the target array, how can I achive that?"

One had to actively mutate the target array by slicing the common item from it which in the very end makes target become the relative complement of source in target ... commonly/vulgo ... the target difference.

One of cause could apply a shallow copy of target as part of the initial value of a reduce task in order to not mutate the original target reference itself ...

function collectIntersectionAndComplements(collector, sourceItem) {
  const { targetDiff } = collector;

  const targetIndex = targetDiff
    .findIndex(targetItem => targetItem === sourceItem);

  if (targetIndex === -1) {

    // collect the relative complement of target
    // in source ... vulgo ... the source difference.
    (collector.sourceDiff ??= [])
      .push(sourceItem)
  } else {

    // collect the intersection of both source and target ...
    (collector.intersection ??= [])
      .push(
        // ... by rejecting the common item from the original
        // target, thus actively mutating the latter, which leads
        // to ending up additionally with the relative complement
        // of source in target ... vulgo ... the target difference.
        targetDiff.splice(targetIndex, 1)[0]
      );
  }
  return collector;
}

const source = [1, 1, 1, 3, 4];
const target = [1, 2, 4, 5, 6];
const {

  intersection,
  sourceDiff,
  targetDiff,

} = source.reduce(collectIntersectionAndComplements, { targetDiff: [...target] });

console.log({ source, target, intersection, sourceDiff, targetDiff });
.as-console-wrapper { min-height: 100%!important; top: 0; }

@heyheyhey2 ... Btw, if one was talking about the Simple Theory of Sets then duplicate (identical) values within each array/list/set were not allowed. Sets always have to feature just unique values.

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
-2

Note that for a single pass both arrays must have been sorted into ascending order.

function go(){
    const a = [0,1, 1, 1, 3, 4, 6,8,10];
    const b = [-3,-4,1, 2, 4, 5, 6,25,26];

    let nomatcha=[];
    let match=[];
    let nomatchb=[];
    let i=0,j=0;
    while(true){
        if(i>=a.length){
            for (;j<b.length;j++) nomatchb.push(b[j]);
            break;
        }
        else if (j>=b.length){
            for (;i<a.length;i++) nomatcha.push(a[j]);
            break;
        }
        else if(a[i]==b[j]){
            match.push(a[i++]);
            j++;
        }
        else if (a[i]<b[j]){
            let val=a[i++];
            if(nomatcha.length==0)nomatcha.push(val);
            else if(val != nomatcha[nomatcha.length-1])
                nomatcha.push(val);
        }
        else if (b[j]<a[i]){
            let val=b[j++];
            if(nomatchb.length==0)nomatchb.push(val);
            else if(val != nomatchb[nomatchb.length-1])
                nomatchb.push(val);
        }


    }

    console.log("match: "+match);
    console.log("nomatcha: "+nomatcha);
    console.log("nomatchb: "+nomatchb);

}

}

Output:

match: 1,4,6 nomatcha: 0,1,3,8,10 nomatchb: -3,-4,2,5,25,26

dave110022
  • 64
  • 5