Sweepster
Sweepster

Reputation: 1949

Trying to detect if one array is missing elements of another

I have the following code which compares array1 to array2 in order to determine if array1 is missing a value from array2:

var array1 = ['bob', 'george'];
var array2 = ['bob', 'george', 'frank'];
var isMissing = false;

console.log(missing(array1, array2));

function missing(a,b) { 
    if (a > b) {
        var length = a.length;
    } else if (b > a) {
        var length = b.length;  
    } else {
        var length = a.length;    
    }

for (var i = 0; i < length; i++ ) {
    if (b.indexOf(a[i]) == -1) {
         isMissing = true;
    } else {
         isMissing = false;        
    }

    if (isMissing == 'true') {
    break;
    }
}

return isMissing;
}

The above doesn't always work though. See below chart for scenarios and results vs expected results:

var array1 = ['bob', 'george'];
var array2 = ['bob', 'george', 'frank']; // result:true, expected: true

var array1 = ['bob', 'frank'];
var array2 = ['bob', 'george', 'frank']; // result:true, expected: true

var array1 = ['frank', 'george'];
var array2 = ['bob', 'george', 'frank']; // result:true, expected: true

var array1 = ['frank', 'bob', 'george'];
var array2 = ['bob', 'george', 'frank']; // result:false, expected: false

var array1 = ['frank', 'george', 'sue', 'frank'];
var array2 = ['bob', 'george', 'frank'];  // result:false, expected: true

var array1 = ['frank', 'george', 'sue', 'frank'];
var array2 = ['bob', 'george', 'frank', 'janet'];  // result:false, expected: true

var array1 = ['frank', 'george'];
var array2 = ['frank', 'frank']; // result: false, expected: true

I'm not sure what the issue is...

I've read this thread but it isn't bearing any fruit for me since I don't need to know which element is missing, I just need to know if there is one missing.

No external libraries please. thanks.

Upvotes: 0

Views: 267

Answers (5)

jo_va
jo_va

Reputation: 13963

Use Array.prototype.some and Array.prototype.indexOf.

Make a copy of the first array, then iterate over the elements of the second array, and find the element in the first array, if it is found, remove it so it won't be counted twice.

const missing = (arr1, arr2) => {
  const left = [...arr1];
  return arr2.some(x => {
    const idx = left.indexOf(x);
    if (idx >= 0) left.splice(idx, 1);
    return idx < 0;
  });
}
  
console.log(missing(['bob', 'george'], ['bob', 'george', 'frank'])); // true
console.log(missing(['bob', 'frank'], ['bob', 'george', 'frank'])); // true
console.log(missing(['frank', 'george'], ['bob', 'george', 'frank'])); // true
console.log(missing(['frank', 'bob', 'george'], ['bob', 'george', 'frank'])); // false
console.log(missing(['frank', 'george', 'sue', 'frank'], ['bob', 'george', 'frank']));  // true
console.log(missing(['frank', 'george', 'sue', 'frank'], ['bob', 'george', 'frank', 'janet'])); // true
console.log(missing(['frank', 'george'], ['frank', 'frank'])); // false

Upvotes: 1

Daniel
Daniel

Reputation: 35684

I was having a hard time understanding how you wanted the second last test to be false, but looks like you updated it

console.log(missing(['bob', 'george'], ['bob', 'george', 'frank']) === true);
console.log(missing(['bob', 'frank'], ['bob', 'george', 'frank']) === true); 
console.log(missing(['frank', 'george'], ['bob', 'george', 'frank']) === true);
console.log(missing(['frank', 'bob', 'george'], ['bob', 'george', 'frank']) === false); 
console.log(missing(['frank', 'george', 'sue', 'frank'], ['bob', 'george', 'frank']) === true);
console.log(missing(['frank', 'george', 'sue', 'frank'], ['bob', 'george', 'frank', 'janet']) === true);
console.log(missing(['frank', 'george'], ['frank', 'frank']) === true);

function missing(a, b) {
  var c = [].concat(a); // non-destructive
  for (var i = 0; i < b.length; i++) {
    var iO = c.indexOf(b[i]);
    if (iO < 0) {
      return true;
    }
    c.splice(iO, 1)
  }
  return false;
}

the function, because you only care about what's NOT in array b, you loop over b and compare to array a, as soon as a missing item is found return true right away otherwise return false at the end

updated to keep track of count

Upvotes: 1

Simone Morettini
Simone Morettini

Reputation: 391

function missing(a,b){
  //remove duplicated elements
  var aa=a.filter(function(elem, index, self) {return index ===self.indexOf(elem);});
  var bb=b.filter(function(elem, index, self) {return index ===self.indexOf(elem);});
  //put in aa the longest array
  if(aa.length<bb.length){
    var tmp=aa;
    aa=bb;
    bb=tmp;
  }
  var result=false;
  //search for an aa's element not in bb
  aa.forEach(el=>{
    if(bb.indexOf(el)<0){
      result=true;
      return;
    }
  });
  return result;
}

var array1 = ['bob', 'george'];
var array2 = ['bob', 'george', 'frank']; // result:true, expected: true
console.log(missing(array2, array1));

var array1 = ['bob', 'frank'];
var array2 = ['bob', 'george', 'frank']; // result:true, expected: true
console.log(missing(array2, array1));

var array1 = ['frank', 'george'];
var array2 = ['bob', 'george', 'frank']; // result:true, expected: true
console.log(missing(array2, array1));

var array1 = ['frank', 'bob', 'george'];
var array2 = ['bob', 'george', 'frank']; // result:false, expected: false
console.log(missing(array2, array1));

var array1 = ['frank', 'george', 'sue', 'frank'];
var array2 = ['bob', 'george', 'frank'];  // result:false, expected: true
console.log(missing(array2, array1));

array1 = ['frank', 'george', 'sue', 'frank'];
array2 = ['bob', 'george', 'frank', 'janet'];  // result:false, expected:true
console.log(missing(array2, array1));

Upvotes: 0

gizyk
gizyk

Reputation: 141

Find first element in second array and remove it.

function missing(a,b) {
  let coppied = [...b];
  a.forEach(el => {
    const index = coppied.indexOf(el);
    if (index != -1) {
      coppied.splice(index, 1);
    }
  });

  return !!coppied.length; //If not empty return true
}

Upvotes: 0

AlexOwl
AlexOwl

Reputation: 867

function missing(array1, array2) {
  const copy = array1.slice()
  return array2.some(element => {
    const index = copy.indexOf(element)
    if(index >= 0) copy.splice(index, 1);
    return index < 0
  })
}


var array1 = ['bob', 'george'];
var array2 = ['bob', 'george', 'frank'];

console.log(missing(array1, array2))

var array1 = ['bob', 'frank'];
var array2 = ['bob', 'george', 'frank'];

console.log(missing(array1, array2))

var array1 = ['frank', 'george'];
var array2 = ['bob', 'george', 'frank'];

console.log(missing(array1, array2))

var array1 = ['frank', 'bob', 'george'];
var array2 = ['bob', 'george', 'frank'];

console.log(missing(array1, array2))

var array1 = ['frank', 'george', 'sue', 'frank'];
var array2 = ['bob', 'george', 'frank'];

console.log(missing(array1, array2))

var array1 = ['frank', 'george', 'sue', 'frank'];
var array2 = ['bob', 'george', 'frank', 'janet'];
console.log(missing(array1, array2))

var array1 = ['frank', 'george'];
var array2 = ['frank', 'frank'];
console.log(missing(array1, array2))

Upvotes: 2

Related Questions