Is filter only solution here in task

@JohnL3 -Thanks, as you suggested i added another loop to loop through testkey and logically it must give right result , after checking for equality of both property and its value , still it returns something like this -

[{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 },{ "a": 1, "b": 2 },{ "a": 1, "b": 2, "c": 2 }]

I tried many combinations of loop but still no success …


function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  // Only change code below this line
  var testkey = Object.keys(source);
  for(var j = 0; j < testkey.length; j++){
  for(var i = 0; i < collection.length; i++){
   if(collection[i].hasOwnProperty(testkey[j])){
 
     if(collection[i][testkey[j]]=== source[testkey[j]]){
      
       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 });

@camperextraordinaire - i am still confused as to why the code is doing what it is doing , my simple thinking says -


 if(collection[i].hasOwnProperty(testkey[j])){ 

this line checks if the collection array of objects at location starting from 0 has a property with key similar to property of source object at location 0 and so on …

And in the below line i check if the values match as well -

if(collection[i][testkey[j]]=== source[testkey[j]]){

But then why is the out put so different , is it due to wrong loop ? Kindly guide …

Regards

@camperextraordinaire - Thanks, so this is how i am thinking about the problem -

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

Here there is an array of objects collection and a object source, now i need to loop through collection objects and compare their key value pair with the object source and if all the key value pair of source are present in collection i push them to arr.

Now i use - var testkey = Object.keys(source);to access the keys in source …

Then in loop -

for(var j = 0; j < testkey.length; j++){
  for(var i = 0; i < collection.length; i++){
   if(collection[i].hasOwnProperty(testkey[j])){
 
     if(collection[i][testkey[j]]=== source[testkey[j]]){
      
       arr.push(collection[i]);
     }
   }
  }
  }

I take values of key from source and match with value of key in collection(hsaOWnProperty), then if that matches, i match their values …

Here i am making a mistake and not being able to find a solution for last six days is how do i after comparing the first key/value , compare the next key/value pairs in source, hence i satisfy the first 2 conditions of task but not the next 2 which have more then one key/value pair in source …

Thanks for your patience

The problem is basically that inside the middle of the two loops you are only testing ONE key. Whether the object gets pushed to the array needs to depend on the presence of ALL the keys so you somehow need to keep track of whether the other ones matched.

One way to do that would be to set a flag inside the first loop “pushThisElement = True” and then let any of the iterations of the inner loop set it to false. It might be easier to have the loop for the source inside the loop for the collection.

I’m afraid I didn’t read the whole rest of the thread so there might be a reason you’re specifically trying to avoid “filter” but it’s conceptually the easiest construct to apply here because what you’re trying to do is filter a list according to complex criteria.

You can write “arr = collection.filter(meetsCriteria);” and then figure out how to write the function “meetsCriteria”.

@r1chard5mith - thanks , i know that i need to check for both values , but i am really struggling to find a proper solution despite the help being offered, i know it must be very easy but somehow i am not able to grasp it …

I do not use filter as i find it very hard to remember functions and feel even more confused as to what exactly happened and what the function did …

ok i added to my other repl it shows what needs to be done but you are going to have to look at it and then implement it in your code.
Go to line 32 read the instructions … I have changed line 33 to have two properties in the test object … then go to line 51 to see test 3 and how it works … basically i created a Boolean variable set to false … then check if object has property and is equal to test property and if so Boolean = true if not false and break after it checks Boolean and if true pushes to array …

@JohnL3 - thanks as per your code i made the changes but its not working , i am still doing something wrong , also at line 38 of your code here -

if( objA.hasOwnProperty(testKeyB)) {

and the below values match with -


let testB = {firstname: 'Emily', age: 11};
let testKeyB = Object.keys(testB);

let objB = { firstname: 'Emily', age: 11};

still in output window it says -

objA dose not have the property …firstname,age

objB dose not have the property …firstname,age

Now in my code again it returns -

[{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 },{ "a": 1, "b": 2 }, { "a": 1, "b": 2, "c": 2 }]


function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  // Only change code below this line
  var tr = false;
  var testkey = Object.keys(source);
  for(var j = 0; j < testkey.length; j++){
  for(var i = 0; i < collection.length; i++){
   if(collection[i].hasOwnProperty(testkey[j])){
 
     if(collection[i][testkey[j]]=== source[testkey[j]]){
      
      // arr.push(collection[i]);
       tr = true;
     }
     else{
       tr = false;
       break;
     }
     
    if(tr) {
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 });

Could you please guide where i am wrong , thanks for your patience …

Regards

Lol ignore that part … i added a property to test object and didnt update that section as i wrote new section below.

Anyway your getting close … you have every thing but just not in right order … and you logic is a little out
eg

for (let x = 0; x <collection.length etc){
for(let y =0; y< testKey.length etc etc) {
if(collection[x].hasOwnProperty(testkey[y])){ // the else is connected to this if
                                                   // in here    if(collection[x][testkey[y]] === source[testkey[y]]){
                                                     //               tr= true;
                                                       //                     }
         } else {
           tr = false;
           break;
         }
        if(tr) etc;
   } // closing for testKey loop
} //closing for collection loop

It really helps if you use your console to debug and step through the code line by line and you will see why yours above is failing … so if you not to sure how to debug it really really is important to learn as makes your life a whole lot easier.

if(collection[x].hasOwnProperty(testkey[y])){

          } else {
            tr = false;
            break;
          }
```
Forgot to explain above ... if collection[x].hasOwnProperty(testkey[y]) ... if it has property we want to continue
else we want to set boolean to false as it dosent ...  and we want to break  before it checks next prop 
because if it checks next property and it has it .. tr will become true and it will push object into array

Just as a general matter, I think all filter solutions can be re-written into a vanilla for loop. The built in filter function in Javascript itself uses for loops, so that means you can always rewrite a solution using filter into one using for loops.

But you will want to know how to use filter and other “higher level” array functions eventually because it leads to more readable code. I know it doesn’t seem that way when you are first learning filter but it will make your life easier if you learn it imo.

@JohnL3 -Thanks, i have been trying this for sometime now changing all possible loops and using console.log to debug , but still no success, in the code , as per your code i check for each property and value for being matched , then use false and break and then print the final result after loop, still i keep getting all the values of collection printed twice …

How come be the code wrong now that we use flags …


function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  var i;
  var j;
  // Only change code below this line
  var tr = false;
  var testkey = Object.keys(source);
  for( j = 0; j < testkey.length; j++){
  for( i = 0; i < collection.length; i++){
   if(collection[i].hasOwnProperty(testkey[j])){
 
     if(collection[i][testkey[j]]=== source[testkey[j]]){
      
      // arr.push(collection[i]);
       tr = true;
     }
     else{
       tr = false;
       break;
     }
        
     
   }
 
   if(tr) {
arr.push(collection[i]);

}  
   
   
  }
    
   
     
    
  }
  
   
 console.log(arr);
  
  // 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 });

Slightly adjusted your code … check out below … i also put Big Capitol letters showing where each section starts and ends eg A B C … as you can see its same code you used just reorganized

function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  var i;
  var j;
  // Only change code below this line
  var tr = false;
  var testkey = Object.keys(source);
  for( i = 0; i < collection.length; i++){
  for( j = 0; j < testkey.length; j++){// A
   if(collection[i].hasOwnProperty(testkey[j])){//B
 
     if(collection[i][testkey[j]]=== source[testkey[j]]){ //C 
      
      // arr.push(collection[i]);
       tr = true; 
     } //C
   }  else{ //B
       tr = false;
       break;
     }

  }//A
     if(tr) {
    arr.push(collection[i]); 
   }
    
  }
  
   
 console.log(arr);
  
  // 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 });

@camperextraordinaire @JohnL3 @honmanyau @HassanM - Thank you so much for the help, now i need to tell you that i did not click on the blur and said to myself as to prepare an algorithm to see what i want to achieve … and i kept on console.log for it …

So i said first of all i need to see if the objects in collection contains all the keys in the source array -

var test = Object.keys(source);
console.log(collection[1].hasOwnProperty(test[1]));

So here i checked by changing the values of test[1] etc, once i knew this was correct i then need to loop through the collection and put it on the outer as all values of collection needs to be checked …

Earlier i had put source in the outer loop …

Once i did that i checked for the values , now for values of source , i would need to use -

	for(var key in source){  /// this helps me get key values
source[key]

So now i have -

if(collection[i][key] == source[key]){
Then i would use flags, another logical mistake i was making was of accepting values even if they were not satisfying full conditions ...

Then here is  my final code - 



function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  var test = Object.keys(source);
  for(var i = 0; i < collection.length; i++){
  	for(var j = 0; j < test.length; j++){
  		if(collection[i].hasOwnProperty(test[j])){
      		for(var key in source){
          	if(collection[i][key] == source[key]){
            	tr = true;
      
            }
            
            else{
            tr = false;
            }
          
          }
  			
      }
  	}
     if(tr){
 arr.push(collection[i]);
 }
}
  

// console.log(collection[1]["a"]);
//console.log(collection[1].hasOwnProperty(test[1]));
//console.log(collection[0]["a"]);
//console.log(source["a"]);
//console.log(collection[0]["a"]);
//console.log(Object.keys([source][0]));
//console.log(source["a"]);
console.log(arr);
  return arr;
}

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

Thanks a lot and i will keep coming back a lot as i find hard to understand shortcut solutions and can only work and understand when i can fit the solution in the way i am thinking …So after 8 days finally through this task :):smiley:

Regards

3 Likes