Frnak
Frnak

Reputation: 6802

Get one element of object that is NOT contained in array

I want to return one element of an object, that is not contained in an array

I have the following array for example:

var aArray = [{ABC: { BADGE: "ABC" }}, {BCA: { BADGE: "BCA"}}]

And the following object:

var oObject = {
    A: {
        ABC: "ABC",
        BCA: "BCA"
    },
    B: {
        BCA: "BCA",
        AAA: "AAA"
    }
}

so what I would expect is to get AAA

currently I 'm struggling with the following code:

for(var j = 0; j < aArray.length; j++) {
    bNotFound = true;

    for(var biz in oObject) {
        for(var badge in oObject[biz]) {
            if(badge == aArray[j].BADGE) {
                bNotFound == false;
            }
        }   
    }

    if(bNotFound) {
        // Return Badge
    }
}

This would work - however I don't know which element to return at the // Return Badge position, cause I only know, that no element was found.

Any suggestions?

UPDATE:

Desired output:

{AAA: "AAA"}

Upvotes: 0

Views: 88

Answers (2)

AntouanK
AntouanK

Reputation: 4978

I would take a more "functional" approach, so I can easily change the process later if needed.

For example

'use strict';

var aArray = [{ABC: { BADGE: "ABC" }}, {BCA: { BADGE: "BCA"}}];
var oObject = {
    A: {
        ABC: "ABC",
        BCA: "BCA"
    },
    B: {
        BCA: "BCA",
        AAA: "AAA"
    }
};
var results = [];

//  first make a function that checks if the value given is in the array's values
var isValueInArray = (function(){

  var flatArray = [];
  aArray
  .map(function(obj){

    return Object.keys(obj)
    .map(function(key){ 
      return obj[key].BADGE;
    });
  })
  .forEach(function(ar){ 
    flatArray = flatArray.concat(ar);
  });

  return function(value){
    return flatArray.indexOf(value) !== -1;
  };
})();


//  then push the values by whether they exist in the flat array

Object.keys(oObject)
.forEach(function(key){

  var thisObj = oObject[key];

  Object.keys(thisObj)
  .forEach(function(key){

    if( !isValueInArray(thisObj[key]) ){
      var obj = {};
      obj[key] = thisObj[key];
      results.push(obj);
    }
  });
});

//  results has the ... results
console.log(results);

Upvotes: 1

Fabian Streitel
Fabian Streitel

Reputation: 2810

Sorry, misunderstood your question. You need to reverse the loops: loop over the object first, then over the array. Then you can return the badge if it wasn't found in the array.

function findBadge() {
    for(var biz in oObject) {
        for(var badge in oObject[biz]) {
            var found = false;
            for(var j = 0; j < aArray.length; j++) {
                if(badge == aArray[j].BADGE) {
                    // found it in the array
                    found = true;
                    break;
                }
            }   
            if (!found) {
                return badge;
            }
        }
    }

    // no badge was found that is not in the array
    return null;
}

Though I would suggest you rethink your data structures. I don't know what they are supposed to represent, but they seem overly complex for the task at hand. E.g. the array could simply be ["ABC", "BCA"] and you could use Array#indexOf to search for the badges.

Upvotes: 1

Related Questions