Wherefore art thou

function whatIsInAName(collection, source) {


for(let i = 0; i < collection.length; i += 1) {
  if (Object.prototype.hasOwnProperty(source) && Object.keys(collection));
}
return source;
}

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

This one has me so confused. Can someone help me out without giving me the answer?

1 Like

This one caused me headaches when I first tackled it, though it’s a really useful exercise.

There are a few different ways of approaching this. You can use methods such as filter, each, every… or you can just use nested for loops.

The key thing is that for each object in the collection array, you need to check if the object contains all matching key/value pairs from the source object. So you need to iterate both the array and the source object.

The advantage of a method like filter is that it can simply remove all ‘invalid’ objects from the collection array directly.
One issue with not using a filter is that you have to find some other way of accepting/rejecting each of the collection objects (and perhaps pushing them to a results array).

Using Object.keys() could be a handy way of iterating the source object or, if you want to use nested for loops, you could use a for ... in loop on the source object.

I hope that is a useful starting point?

Thanks for your response!

This one is so tough. I have been sitting with it for hours and getting nowhere. I’m trying to break it down in simple steps to make it easier but I don’t know if it’s helping me.

So correct me if I am wrong, for this problem you basically have to filter out all the arrays in ‘collection’ that contain what they are supposed to contain, then add the leftover array that had a different value… to the source?

Not exactly.

You have an array of objects (collection). The challenge requires you to return an array containing all of the objects in collection which contain all matching key/value pairs from the source object.

The filter method is one possible approach as it takes an array and filters out all items in the array which don’t meet the specified condition.

Here’s a simple filter example:

function filterOutOdds(arr) {
  return arr.filter(item => item % 2 == 0)
}

console.log(filterOutOdds([1, 2, 3, 4, 5, 6, 7, 8, 9]))
// returns [2, 4, 6, 8]

This function takes an array (arr) and returns it with the filtered items removed. The filter method iterates over each item in the array and checks if the condition is true or false. In this case, it checks if the remainder of dividing by 2 is 0 (i.e. is it an even number). If the answer is false, the item is removed from the array. So the function will return only the even numbers in the array.

NOTE: item => item % 2 == 0 is just a simple callback function in arrow syntax. You could also write the function within the parentheses as:

function (item) {
  return item % 2 == 0
}

So you could use filter on your collection array. You would write a callback function which says ‘does this array item match with all key/value pairs in source’? Any which don’t would be filtered out.

Returning the filtered array would then meet the criteria of the challenge.

More about filter:

2 Likes

Thank you so much for your help! I really appreciate it.

function whatIsInAName(collection, source) {

return collection.filter(item => item != source); 

}

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

What I wrote still doesn’t work, but I thought this basically says filter any array in the collection that doesn’t contain the same item in the source. Therefore, I would think [{ first: "Tybalt", last: "Capulet" }] would be the only array left. Is my logic off?

Yes, your logic isn’t quite right. Like I said, you need to iterate the source object as well as the array. You are not looking for objects which match the source object exactly. You are looking for objects which contain the same key/value pairs as the source object.

EXAMPLE:

// an object from a collection array
{first: "Bob", last: "Hope", age: 119}

// the source object
{first: "Bob", last: "Hope"}

The collection object does not match the source object but should be returned by the filter because it DOES match both of the key/value pairs in the source object.

What you’ll need to do, within your filter callback function, is check if the collection object contains all of the key/value pairs from the source object. You could get the object keys from source with Object.keys() perhaps?

Thanks for your patience with me, I really appreciate it :pray:

function whatIsInAName(collection, source) {

return collection.filter(item => item == Object.keys(source) && Object.values(source)); 

}

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

I thought this new attempt says filter anything in the collection that doesn’t have both the object key from the source and the value. Which in this case is basically saying Object.key(last:) and Object.value(Capulet). To me what I am writing makes sense but I know I must be doing something wrong

What does Object.keys(source) give you exactly?

Look at the first example given here to see what it returns:

For that example it returns ["a", "b", "c"] which I thought would be the equivalent to me asking for the object key in source [“last”], but I am wrong?

Because if the source is { last: "Capulet" }, isn’t Object.key(source) = ["last"]. Same as if the {a: 'somestring'}, then the Object.key(object1) would be ["a"], right?

Ok, so if the source object were:

{ "apple": 1, "bat": 2, "cookie": 2 }

What exactly would Object.keys(source) return?

["apple", "bat", "cookie" ]

Right?

Yes, so your function is comparing a collection object (e.g. { "apple": 1, "bat": 2 }), with an array (e.g. ["apple", "bat", "cookie" ]). This is not a useful comparison.

Now that you have the object keys from source, you need to compare each of them (and their corresponding values) against each of the object keys and values in each collection object). So, you need to iterate the source keys, as well as the collection (which is being iterated by the filter method).

function whatIsInAName(collection, source) {



for (let i = 0; i < collection.length; i += 1) {
  if (Object.keys(source) && Object.values(source) == Object.keys(collection) && Object.values(collection));
} 
return collection;
};


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

Not to sidetrack from what you just said, but while I was waiting for you to reply I tried to see if using a for loop would be easier, but now I will go back to trying to get the filter method to work

What does Object.keys and Object.values do?
You seem to have a plan but are trying syntax without being sure what it does?

Like I like to say, 95% of the time, for and if are the overwhelming majority of syntax you need, so you should thoroughly research any ‘extra’ syntax you use.

Object.keys take all of the keys in a string and turns it into an array. While Object.values turns all the values in a string into an array. So something like
{1: 'brownies', 2: 'vanilla', 3: 'mint' };

Object.keys(source) would be [“1”, “2”, “3”]. The Object.values(source) would be [“brownies”, “vanilla”, “mint”]

So why do you want those results where you put them?

Yes, I see, what I wrote doesn’t make any sense

Is it just me or does it seem unfair for FCC to expect someone that’s a month into coding to complete a problem like this? Took 10 days to complete HTML/CSS section and been on Java for a little over 3 weeks now. I did everything prior to this by reading the instructions, looking at the example they give, hints, asking for help, etc. This Intermediate Algorithm Scripting section seems like everything just took a giant leap. Like in basketball terms…I was learning how to dribble and do layups at a nice pace…then BAM…I’m now being told to dunk and hit half-court shots like Curry. :sob:

*Don’t mind my lil vent…I’m just saying

I think this piece of syntax is helpful

And you can use this with if and for to create a solution.

The question is, what kind of a plan does this Object.keys let you make?

I would think starting my code with something like let keysSrc = Object.keys(source); …would allow me to use if statements to compare the keys in the source to the keys in the collection.

Can this problem be summed up in these 3 notes?

// Let keys in source = object.keys(source)
// Let value in source = object.values(source)
// if both the values and keys in the source are found in an array in the collection, then return that array

I think Object.values is leading you astray. Ignore it.