# freeCodeCamp Algorithm Challenge Guide: Wherefore Art Thou

freeCodeCamp Algorithm Challenge Guide: Wherefore Art Thou
0.0 0

#1

Remember to use `Read-Search-Ask` if you get stuck. Try to pair program and write your own code

### Problem Explanation:

Write an algorithm that will take an `array` for the first argument and return an `array` with all the `object`s that matches all the properties and values in the `Object` passed as second parameter.

## Hint: 1

You may use `for` loop or the `Array.prototype.filter` method.

try to solve the problem now

## Hint: 2

Try to use the `Object.prototype.hasOwnProperty` method to know if the property name exists in an object (as its own property).

try to solve the problem now

## Hint: 3

Check equivalence of `Object` in `collection` with `Object` passed as second parameter to `whatIsInAName` function.

try to solve the problem now

## Basic Code Solution:

``````function whatIsInAName(collection, source) {
// "What's in a name? that which we call a rose
// By any other name would smell as sweet.ā
// -- by William Shakespeare, Romeo and Juliet
var srcKeys = Object.keys(source);

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

// test here
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
``````

### Code Explanation:

• We filter through the array using `.filter()`.
• Using a `for loop` we loop through each item in the object.
• We use a `if statement` to check if the object in the collection doesnāt have the key and the property value doesnāt match the value in source.
• We return `false` if the above `if statement` is correct. Otherwise, we return `true`;

## Intermediate Code Solution:

``````function whatIsInAName(collection, source) {
// "What's in a name? that which we call a rose
// By any other name would smell as sweet.ā
// -- by William Shakespeare, Romeo and Juliet
var srcKeys = Object.keys(source);

return collection.filter(function (obj) {
return srcKeys.every(function (key) {
return obj.hasOwnProperty(key) && obj[key] === source[key];
});
});
}

// test here
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
``````

### Code Explanation:

• We filter through the collection using `.filter()`.
• Next, we return a `Boolean` value for the `.filter()` method.
• Finally, we reduce to `Boolean` value to be returned for the `.every()` method.

``````function whatIsInAName(collection, source) {
// "What's in a name? that which we call a rose
// By any other name would smell as sweet.ā
// -- by William Shakespeare, Romeo and Juliet
var srcKeys = Object.keys(source);

// filter the collection
return collection.filter(function (obj) {
return srcKeys
.map(function(key) {
return obj.hasOwnProperty(key) && obj[key] === source[key];
})
.reduce(function(a, b) {
return a && b;
});
});
}

// test here
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
``````

### Code Explanation:

• We start by filtering through `collection` using `Array.filter()`.
• Next, we map through all keys and return Boolean values based on the check conditions: both the key and its corresponding value must exist within the object we are filtering through.
• Then we reduce the mapped Boolean values to a single Boolean that indicates whether all srcKeys pass the conditions checked above.
• This single Boolean will be used to filter through the collection.

## NOTES FOR CONTRIBUTIONS:

• DO NOT add solutions that are similar to any existing solutions. If you think it is similar but better, then try to merge (or replace) the existing similar solution.
• Categorize the solution in one of the following categories ā Basic, Intermediate and Advanced.

See `Wiki Challenge Solution Template` for reference.

Question about reduce method - freeCodeCamp Algorithm Challenge Guide: Wherefore Art Thou
#2

There is a bug in the āadvancedā solution above. I made a PR to the old `wiki` project, but was told to contribute here instead. Would be great if the āadvancedā solution could be updated. Details can be found here: https://github.com/FreeCodeCamp/wiki/pull/1246

#4

@sautille is still a ānew userā, once enough trust/reputation is built to progress to ābasic userā people can edit wiki posts.

From memory you just need to read a few posts and interact a little to ālevel upā.

Edit

#6

This is just a basic mechanism to avoid spaming.

#7

@sautille: I have updated the changes to match and reflect the pull request you made earlier and the change on the main repository as well.

Thanks for contributing.

#8

Great post i apprecialte your efforts!

#9

#10

#11

Iāve tried to solve this and gotten 2/4 green marks but gave up and came here to take a peek.

But I only got more confused. The exersize says to only change code between the lines.

`````` var arr = [];
// Only change code below this line

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

But all the solutions posted here ignore that.

#12

I also got 2/4 green marks using the code belowā¦ I understand why my code doesnāt work but I was wondering if anyone knows if itās possible to make this approach work (without using the filter() method) considering that the exercise tells us not to change the code between the lines. Cheers!

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

#13

@jacobworrel I think your code is pushing to arr when only ONE property is matched. However, sometimes the source has more than one, an all must be matched.

#14

Right.I just wonder if thereās any way to make my code work when there is more than one propertyā¦

#15

Help! Can anyone tell me why my code removed the `""` from the keys in my solution?
Hereās my code:

``````function whatIsInAName(collection, source) {
var arr=[];
var k = Object.getOwnPropertyNames(source);
var v = source[k]; // assigns var to value in key value pair

//loop through array of objects
for (var i = 0; i < collection.length; i++) {

//check each object for matching key
if (collection[i].hasOwnProperty(k)) {

if (collection[i][k] == v ) { // if object has a match of key value pair...
arr.push(collection[i]); // add object to arr
}
}
}
return arr;
}
``````

The code passed for the 1st test:

`whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });`

but the 2nd didnt pass (keys arenāt in double quotes).

2nd test:
`whatIsInAName([{ "a": 1 }, { "a": 1 }, { "a": 1, "b": 2 }], { "a": 1 })`

my function returned this:

`[ { a: 1 }, { a: 1 }, { a: 1, b: 2 } ]`

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

Why were my keys changed when I pushed them to arr?

And why do none of the spoiler solutions use the starter code that was there? (where the last line is `return arr`?)

#16

Is it the answer they were looking for? Probably not, given the replies, but I found a solution that works and just thought I would pass it on. Cheers!

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

var name,
key,
soVal,
coVal;
for(name in source){
soVal = source[name];
}
var i=0;
for(i; i< collection.length; i++) {
var obj = collection[i];
for(key in obj){
coVal = obj[key];
if (coVal == soVal && name == key) {
arr.push(obj);
}
}
}

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

#17

FYI, the code above for the advanced solution is corrected, but the repl.it it links to still has the old code.

#18

the filter() method works as well

#19

This solution worked for me and it shares your approach. It passed all the test cases.

``````function whatIsInAName(collection, source) {
var arr = [];
for (var keyd in source){
}for (var key in collection){
if (source[keyd] === collection[key][keyd]){
arr.push(collection[key]);}
}return(arr);}``````

#20

I solved this with a comparing the objects.
Here is the code:

``````function whatIsInAName(collection, source) {
// What's in a name?
return collection
.filter((obj) => JSON.stringify(Object.assign(JSON.parse(JSON.stringify(obj)), source)) === JSON.stringify(obj));
}
``````

Does comparing the objects works faster or slower relatively to using the loop with comparing properties. (Sry for bad English )

#21

I solved that with couple for loops, it is not elegant as some above solutions, but it works:

``````function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];

arr = Array.prototype.slice.call(arguments);
// Only change code below this line

var key = Object.keys(source);
var returncollection =[];

for (i=0; i<collection.length; i++)
{
for (j=0; j<key.length; j++)
{
if (collection[i].length<key.length)
{
break;
}
if (collection[i][key[j]]!==source[key[j]])
{
break;
}
if (j==key.length-1)
{
returncollection = returncollection.concat(collection[i]);
}
}
}
//collection2 = collection2.concat(collection[i]);

// Only change code above this line Object.keys(collection[i])[j]
return returncollection;
}``````

#22

Some really interesting solutions in here.

Here is my solution that turned out pretty close to the basic spoiler. I even ended up using some same variable names by coincidence.

I couldnāt figure out an elegant solution in the if/else statement like the basic solution spoiler does on this line:
`if(!obj.hasOwnProperty(srcKeys[i]) || obj[srcKeys[i]] !== source[srcKeys[i]])`
but I figured out an interesting way to get my return to be true if the tests were passed.

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

arr = collection.filter(function(obj) {
var srcKeys = Object.keys(source);
var test = 0;
for (var i = 0; i < srcKeys.length; i++) {
if (obj.hasOwnProperty(srcKeys[i]) && obj[srcKeys[i]] === source[srcKeys[i]]) {
test += 1;
} else {
test += -1;
}
}
return test === srcKeys.length;
});

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

whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
``````