Intermediate Algorithm Scripting: Wherefore art thou - Confused

Needless to say that I’ve spent two days trying to figure this out and I can’t get my head around it.
First the Object.keys was new and I read all I could on the subject but I still don’t understand it
Next, I’ve added in one of the three conditions that are still failing. This one is supposed to return [].
But the way I’ve written my code I’m still generating {object, Object] instead of an empty array.

Can anyone please explain this lesson and where I went wrong?

``````function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
var skeys = Object.keys(source);
for (var i = 0; i < collection.length; i++){
var j = skeys.length - 1;
if (collection[i][skeys[j]] === source[skeys[j]]){
arr.push(collection[i]);
}
}
console.log(arr);
// Only change code above this line
return arr;
}

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

https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/wherefore-art-thou/

The problem with your logic is you push collection[i] if the value of the last property/value pair of the collection[i] object matches any property/value pair of the source object.

Instead, you must make sure all of the property/value pairs of source are in each collection[i].

For example, in the following test case:

``````whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 })
``````

your function returns:

``````[
{ apple: 1, bat: 2 },
{ bat: 2 },
{ apple: 1, bat: 2, cookie: 2 }
]
``````

instead of:

``````[
{ apple: 1, bat: 2 },
{ apple: 1, bat: 2, cookie: 2 }
]
``````

UPDATE: I modified my reply above to correctly reflect what is happening in your existing code.

Thanks
I’ll beat it to death for another day and get back to you :-s

In the above line you are setting the value of j to be the same for every collection[i]. Part of the solution is changing j, so you are checking all sKeys and not just the the last one.

I tried making j a for loop as well but I couldn’t work out how to build the result.
Well I abandoned the last code I just wasn’t getting it. So I tried a filter to sort out my keys but it still doesn’t work. I got it to work with a code solution which I’ve commented out but I want to work through this on my own.

``````function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
var skeys = Object.keys(source);
/*return collection.filter(function(newCol){
return skeys.map(function(key){
return newCol.hasOwnProperty(key) && newCol[key] === source[key];
})
.reduce((a, b) => a && b);
});*/
return collection.filter(function(key){
for (var i = 0; i < skeys.length; i++){
if (key.hasOwnProperty(skeys[i]) || key[skeys[i]] === source[skeys[i]]){
return true;
}
else return false;
}
});

console.log(arr);
// Only change code above this line
return arr;
}

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

I added some console.log statements to your code, so you can better see what is going on during execution.

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

return collection.filter(function(key){
for (var i = 0; i < skeys.length; i++){
console.log('key = ' + JSON.stringify(key) +'\n')
console.log('skeys['+i+'] = ' + skeys[i])
console.log('key[skeys['+i+']] = ' + key[skeys[i]])
console.log('source[skeys['+i+']] = ' + source[skeys[i]])
if (key.hasOwnProperty(skeys[i]) || key[skeys[i]] === source[skeys[i]]){
console.log(true)
return true;
}
else {
console.log(false)
return false;
}
}
console.log()
});

console.log(arr);
// Only change code above this line
return arr;
}

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

/* above code displays the following to the console

key = {"a":1,"b":2,"c":3}

skeys[0] = a
key[skeys[0]] = 1
source[skeys[0]] = 1
true

*/
``````

and the function returns [ { a: 1, b: 2, c: 3 } ]

1 Like

Thanks
When sKeys[1] = b shouldn’t it fail since key[sKeys[1]] and source[keys[1]] are not equal?
I’m passing the first three tests when I changed the || to && but the last three tests fail

|| means OR and && means AND. Only one condition has to be true with || and both have to be true with &&.

Yes thanks
When I changed it I passed the first test as well as the second two but I’m still failing on the last three
So both conditions are required to pass the test for hasOwnProperty
I don’t get why I’m returning collection and not comparing with source?

Well…after three days I checked the solutions and found one that does pretty much the same as mine but it checks for the keys and properties don’t match. At least I learned a lot of new functions, hopefully the next test is more straightforward.

Thanks Randell for your help

Final code:

``````function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
var sKeys = Object.keys(source);
/*return collection.filter(function(newCol){
return skeys.map(function(key){
return newCol.hasOwnProperty(key) && newCol[key] === source[key];
})
.reduce((a, b) => a && b);
});*/
return collection.filter(function(key){
for (var i = 0; i < sKeys.length; i++){
if (!key.hasOwnProperty(sKeys[i]) || key[sKeys[i]] !== source[sKeys[i]]){
return false;
}
}
return true;

});

/*return collection.filter(function (key) {
for(var i = 0; i < sKeys.length; i++) {
if(!key.hasOwnProperty(sKeys[i]) || key[sKeys[i]] !== source[sKeys[i]]) {
return false;
}
}
return true;
});*/

console.log(arr);
// Only change code above this line
return arr;
}

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