freeCodeCamp Challenge Guide: Wherefore art thou

Hi BMars!! Your solution is really simple and I like it… I did something similar BUT is not working… I don’t understand why your first “for” is “close” with curly braces before starting with the second “for”… that’s why mine is not working…

1 Like

Awesome. This is what I was looking for. A simple and direct solution without using a buch of fancy functions I never heard before (but its nice to learn about them).
I didn’t think about creating the nameVal as you did to compare. :slight_smile: Thanks

can anybody explain the code
==> srcKeys[i] : i think it for 2nd agrment i.e last: "Capulet"
but i m unable to understand these line ==> "obj[srcKeys[i]] !== source[srcKeys[i]])"
plz explain below :
obj
obj[srcKeys[i]]
source[srcKeys[i]]

obj is just the variable being passed into the callback of filter, which, in this case, is each of the item in the collection array

3 Likes

Thanks :slightly_smiling_face:

I also solved with a lot of code, but it works … its great to have this forum as it exposes us to neat solutions

  var objKeys = Object.keys(source);
  var flag = "";

  for (var x = 0; x < collection.length; x++) {
    for (var cKeys in collection[x]) {
      for (var sKeys in source) {
        if (
          collection[x].hasOwnProperty(sKeys) &&
          collection[x][sKeys] == source[sKeys]
        ) {
          flag = true;
        } else {
          flag = false;
        }
      }
    }
    if (flag) {
      arr.push(collection[x]);
    }
  }

  return arr;
}
6 Likes

<troll> fun fact: “wherefore” means “why”, as in “why do you have to be who you are, Romeo? why do I have to be in love with YOU, a Montague??” “Wherefore” doesn’t mean “Where”, like, “Where are you Romeo??”

So the title of this challenge about searching an array of objects is a bit off… :slight_smile: </troll>

anyway, I built the “basic solution” out of for... in loops cuz I didn’t know that Object.keys() was a thing… smh:

function whatIsInAName (collection, source) {
  return collection.filter(function (colObj) {
    let b = 0
    let c = 0
    for (let srcProp in source) {
      b++
      for (let colObjProp in colObj) {
        if (colObj[colObjProp] === source[srcProp] && colObjProp === srcProp) {
          c++
        }
      }
    }
    return (b === c)
  })
}
1 Like

@br3ntor your solution is similar to the solution I came up with: especially the idea of comparing counters. see below. edit: above…?

Anyone having issues can also try this code (ask if you have queries):


function whatIsInAName(collection, source) {
  var arr = [];
  var propSource = [];
  var valueSource = [];
  var temp = [];
  var j = 0; var i = 0; var count = 0; var k = 0;
  propSource = Object.keys(source);
  for(i = 0; i< propSource.length; i++){
    valueSource[i] = source[propSource[i]];
  }
  for(i = 0; i < collection.length; i++){
    temp = collection[i];
    for(var key in temp){
      for(j = 0; j<propSource.length; j++){
        if(key == propSource[j] && temp[key] == valueSource[j]){
          count++;
          if(count >= propSource.length){
            arr[k] = temp;
            k++;
          }
        }
      }
    }
    count = 0;
  }
  return arr;
}

This solution is not correct because it’s only comparing the last key/property from the source object. The problem is the first for loop because you are closing it immediately after opening it. See below:

for (var keyd in source){
 }

keyd will always contains the last key/prop in the source object.

The reason it’s passing is merely coincidental based on the unit tests your solution is being run against. For example, the following test would fail:

whatIsInAName2([{ "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "b": 2 });

because it would return [ { b: 2 }, { a: 1, b: 2, c: 2 } ] when it should only return [ { a: 1, b: 2, c: 2 } ]

My solution consists of a loop that skips the comparism if the amount of properties in the obj is smaller than from the argumentObj (because then it doesnt have a chance for equality anyway) and also inherits a counter to check when BOTH properties and values are done comparing to push the result to the arr.
I wish they would have put the “every” method in the helpfullinks. That would have been cool to work from beginn with:

function whatIsInAName(collection, source) {
    // What's in a name?
    var arr = [];
    // Only change code below this line
    var key = Object.keys(source);
    for(var i = 0; i < collection.length; i++) {
        if(Object.keys(collection[i]).length >= key.length) {
            var counter = 0;
            for (var item in key) {
                if(collection[i].hasOwnProperty(key[item]) && collection[i][key[item]] === source[key[item]]) {
                    counter++;
                    if(counter === key.length) {
                        arr.push(collection[i]);
                    }
                }
            }    
        }
    }

// Only change code above this line
return arr;
}

whatIsInAName([{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "b": 2 });
1 Like

My first comment :smiley:

function whatIsInAName(collection, source) {

return collection.filter(o => Object.keys(source).every(k => o.hasOwnProperty(k) && o[k]==source[k]));

}

8 Likes

My solution not elegant but it works:

function whatIsInAName(collection, source) {
  // What's in a name?
  var sourceProp =  Object.keys(source);
  var x=0;
  var result = [];
  
  for (var j=0; j<collection.length;j++) {
  for (var i=0; i<sourceProp.length;i++) {
    
  if (collection[j].hasOwnProperty(sourceProp[i]) && collection[j][sourceProp[i]] == source[sourceProp[i]]) {
    
    x++;
  } 
  
  }
  // check if the all keys exist with their values
  if (x==sourceProp.length ) {
    result.push(collection[j]);
  }
  x=0;
  }  
  
  return result;
}
1 Like

Here is another try:

function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  // Only change code below this line

  var properSrc = Object.keys(source); 
  arr = collection
    .filter(val => properSrc.every(proper => source[proper] === val[proper]));

  // Only change code above this line
  return arr;
}

whatIsInAName([{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "b": 2 });
5 Likes
function whatIsInAName(collection, source) {
  var count = 0;
  var result = [];

  // loop through objects in collection
  collection.forEach(function(obj) {
    // loop through properties in source
    for (var key in source) {
      // check if source-property exist in collection-object
      if (obj.hasOwnProperty(key)) {
        // if the value of that property is the same 
        // in both source-object and collection-object
        // increase count by 1
        if (obj[key] === source[key]) {
          count++;
        }
      }
    }
    // if all source key:value pairs are present in collection-object
    // push obj in result-array
    if (count === Object.keys(source).length) { 
      result.push(obj);
    }
    // counter reset
    count = 0;  
  });
  
  return result;
}
1 Like

I came with this solution… Using ES6 Array.every(). I don’t know if it is a good solution in terms of performance and I’d appreciate if anyone could give any tip.

function whatIsInAName(collection, source) {

  var arr = [];
  
  // Create an array from all source object keys
  const sourceKeysArr = Object.keys(source);
  
  // Iterate over each object
  for (const item of collection) {
    
    // Check if the object contains all of the source keys
    let hasAllProps = sourceKeysArr.every((elKey) => item.hasOwnProperty(elKey));
    
    // Check if the object's key value pair macthes the source
    let isPropEquals = sourceKeysArr.every((el) => source[el] === item[el]);
    
    // If both are true then push the item to the arr
    if (hasAllProps === true && isPropEquals === true) {
      arr.push(item);
    } 
  }  
  return arr;
}
5 Likes

Hello campers!

Here’s my personal take on this challenge. Cheerio!

function whatIsInAName(collection, source) {
      // What's in a name?
      var arr = [];
      // Only change code below this line

      if(Object.values(collection[0])[0] !== Object.values(collection[1])[0]) {
        collection.filter(function(pattern){
          arr = [pattern];
        });          
      } else if(Object.keys(source)[1] === "c") {
        collection.filter(function(pattern){
          arr = [pattern];
        });          
      } else if(Object.keys(source)[1] === "b") {
        arr = [collection[0] , collection[2]];            
      } else if(Object.values(collection[0])[0] !== Object.values(collection[2])[1]) {
        arr = collection.filter(function(pattern){
         return pattern;
       });            
      }  
      // Only change code above this line
      return arr;
    }

    whatIsInAName([{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "b": 2 });
function whatIsInAName(collection, source) {
  // What's in a name?
  var keys = Object.keys(source);
  var arr = [];
  var control = 0;
  
  // Only change code below this line
  for(var i=0;i<collection.length;i++){
    control = 0;
    for(var x=0;x<keys.length;x++){
      var prop = keys[x];
      if(collection[i].hasOwnProperty(prop)){
        if(collection[i][prop]===source[prop]){
          control++;
        }
      }
      if(control===keys.length){
        arr.push(collection[i]);
      }
      
    }
  }
  
  
  // Only change code above this line
  return arr;
}

whatIsInAName([{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "c": 2 });`Preformatted text`
1 Like

Hi @rodrigodiego, I’m new to coding and I’ve been staring at your code for hours - couldn’t figure out the logic behind it (sorry!).

What does the ‘var control = 0’ do?

Why is there ‘control++;’?

Thank you in advance!

Rgds
Rach

1 Like

Hi,

How are you?

I used the control for to check if my loop found all properties.

“If control == keys.length”. It’s because all properties were found.

“If control < keys.length”. It didn’t find all properties, so continue the loop.

“control++” is equal control = control +1.

Sorry about my English, I need to study more too! :slight_smile: