0

I have two arrays:

arr1 = [1, 2, 3, 1, 2, 3, 4]
arr2 = [1, 3, 1, 1]
arr3 = [1, 1, 2, 2, 3]

Using arr1 as the baseline, arr2 does not match because it contains three 1's whereas arr1 only has two. arr3, however should return true because it has elements from arr1.

I tried

if(_.difference(arr2, arr1).length === 0)

But this does not take into account the number of occurrences

Shamoon
  • 41,293
  • 91
  • 306
  • 570

6 Answers6

2

You could count all value from the first array and iterate the second with every and return early if a value is not given or zero, otherwise decrement the count and go on.

function check(a, b) {
    var count = a.reduce((o, v) => (o[v] = (o[v] || 0) + 1, o), {});
    return b.every(v => count[v] && count[v]--);
}

var arr1 = [1, 2, 3, 1, 2, 3, 4],
    arr2 = [1, 3, 1, 1],
    arr3 = [1, 1, 2, 2, 3];

console.log(check(arr1, arr2)); // false
console.log(check(arr1, arr3)); //  true
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

You can try to loop through second array and compare t against main array if value found make main array cell to false and set flag as true

arr1 = [1, 2, 3, 1, 2, 3, 4]
arr2 = [1, 3, 1, 1]
arr3 = [1, 1, 2, 2, 3]

function checkArray(compareMe, toThis){
  var flag = false;
  
  for(var i = 0; i < toThis.length; i++){
    flag = false;
    for(var j = 0; j < compareMe.length; j++){
      if(compareMe[j] == toThis[i]){
        compareMe[j] = false;
        flag = true;
        break;
      }
    }
  }
  
  return flag;
}

console.log(checkArray(arr1, arr2));
console.log(checkArray(arr1, arr3));
Andam
  • 2,087
  • 1
  • 8
  • 21
1

Try this solution:

const arr1 = [1, 2, 3, 1, 2, 3, 4],
      arr2 = [1, 3, 1, 1],
      arr3 = [1, 1, 2, 2, 3],
      arr4 = [1, 2, 3, 1, 2, 3, 4, 1];

function containsFn(src, trg) {
  const srcCp = src.slice();
  for(let i = 0; i < trg.length; i++) {
    const index = srcCp.indexOf(trg[i]);
    if(index > - 1) {
      srcCp.splice(index, 1);
    } else {
      return false;
    }    
  }
  return true;
}


console.log(containsFn(arr1, arr2));
console.log(containsFn(arr1, arr3));
console.log(containsFn(arr1, arr4));
Fraction
  • 11,668
  • 5
  • 28
  • 48
1

Looks like I'm already late to the party but this would be a recursive solution:

arr1 = [1, 2, 3, 1, 2, 3, 4]
arr2 = [1, 3, 1, 1]
arr3 = [1, 1, 2, 2, 3]

function findAllIn(find, search) {
    if (find.length == 0) {
      return true;
    }
    
    i = search.indexOf(find[0]);
    
    if (i == -1) {
      return false;
    }
    
  return findAllIn(find.slice(1,find.length), search.slice(0,i).concat(search.slice(i+1, search.length)));
}

console.log(findAllIn(arr2, arr1)); // false
console.log(findAllIn(arr3, arr1)); // true
Kilian
  • 51
  • 6
1

This should do the trick

Not efficient but I think it is easy to understand

const count = (x, xs) =>
  xs.reduce((y, xi) => y + (xi === x ? 1 : 0), 0)

const isInclusive = (xs, ys) =>
  xs.every((xi) => count(xi, xs) >= count(xi, ys))

const arr1 = [1, 2, 3, 1, 2, 3, 4]
const arr2 = [1, 3, 1, 1]
const arr3 = [1, 1, 2, 2, 3]

console.log(isInclusive(arr1, arr2))
console.log(isInclusive(arr1, arr3))
Chris Vouga
  • 555
  • 6
  • 8
0

Based on this answer: https://stackoverflow.com/a/4026828/3838031

You can do this:

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

arr1 = [1, 2, 3, 1, 2, 3, 4]
arr2 = [1, 3, 1, 1]
arr3 = [1, 1, 2, 2, 3]

console.log((arr1.diff(arr2).length === 0) ? "True" : "False");
console.log((arr1.diff(arr3).length === 0) ? "True" : "False");
console.log((arr2.diff(arr1).length === 0) ? "True" : "False");
console.log((arr2.diff(arr3).length === 0) ? "True" : "False");
console.log((arr3.diff(arr1).length === 0) ? "True" : "False");
console.log((arr3.diff(arr2).length === 0) ? "True" : "False");