Help with where art thou

I’m not seeing why this isn’t working. I commented my thought process which is that if collection[i] has the property in source then it would push collection[i] to arr.

I feel maybe I’m not doing something right with the fact that these are objects? It might be checking if the entire collection has the source? Please let me know, thanks

  **Your code so far**

function whatIsInAName(collection, source) {
var arr = [];
// Only change code below this line

// loop through collection 
for (let i = 0; i < collection.length; i++) {
// if collection includes source then push it to arr
  if (collection[i].hasOwnProperty(source)) {
    arr.push(collection[i]);
  }
}
// Only change code above this line
return arr;
}

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

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36.

Challenge: Wherefore art thou

Link to the challenge:

The second argument passed into the function is an object, for example:

{ last: "Capulet" }

hasOwnProperty takes the name of an object property, not an object, so you aren’t using this function correctly.

Second, take a close look at the output when you run the tests. Notice that source does not always contain just one property/value pair. For example:

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

The source for that function call has two property/value pairs. So you’ll need to check each object in the collection array for both of those.

Damn it sucks it’s my second time on this, this is where I stopped last month and went back to past sections, but I still don’t know what to do. Here is what I’m thinking:

I remember the for in approach may have been the way to go but it’s not right yet it seems

function whatIsInAName(collection, source) {
  var arr = [];
  // Only change code below this line
  
  for (var property in source) {
    if (collection.hasOwnProperty("${property}: ${source[property]}")) {
      arr.push(collection);
    }
  }
  return arr;
}

It looks like these issues fit in the category of ‘what are the data types of the inputs’, much like the one vs many issue you had the other day.

You have two inputs

  1. collection - an array of objects
  2. source - a test object

Your function needs to return a new array that contains all of the objects in collection that have the same properties as the source and set to the same value

collection is an array. It won’t have the same properties as the source

Ok so maybe use another for in to get the properties and then use hasOwnProperty?

Might work, depending on how you structure it

Ok I’m trying but for some reason I can’t get console to log the properties of the collection object but it works for source. Any clue why?

for (const property in collection) {
  console.log(`${property}: ${collection[property]}`);
}
// 0: [object Object]
//1: [object Object]
//2: [object Object]

for (const property in source) {
  console.log(`${property}: ${source[property]}`);
}
//apple: 1
//cookie: 2

I’m not sure if this would be the right approach but I’m going this direction

function whatIsInAName(collection, source) {
  var arr = [];
  // Only change code below this line
  
  for (var property in source) {
    for (var property in collection) {
     if (collection.hasOwnProperty(`${property}: ${source[property]}`)) {
      arr.push(collection);
    }
  }
  return arr;
}
}

console.log(whatIsInAName([{ "apple": 1, "bat": 2 }, { "apple": 1 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "cookie": 2 }));
// should return { "apple": 1, "bat": 2, "cookie": 2 }

You can’t recycle the variable name. The inner definition is shadowing the outer definition.


function whatIsInAName(collection, source) {
  for (var property in source) {
    console.log(property);
    for (var property in collection) {
      console.log(property);
    }
  }
}

whatIsInAName([{ "apple": 1, "bat": 2 }, { "apple": 1 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "cookie": 2 });
function whatIsInAName(collection, source) {
  var arr = [];
  // Only change code below this line
  
  for (var property in source) {
    console.log(property);
    for (var prop in collection) {
      console.log(prop);
     if (collection.hasOwnProperty(`${property}: ${source[property]}`)) {
      arr.push(collection);
    }
  }
  return arr;
}
}

Ok now getting

apple
0
1
2

To be clear am I on the right track?

You can use those two loops, yea. But you should only push when the item in the collection has every property from the source (and set to the same value).

Ah just this but not working

for (var property in source) {
    for (var prop in collection) {
     if (collection.every(prop => collection.hasOwnProperty(`${property}: ${source[property]}`)) {
      arr.push(collection);
    }
  }
  return arr;
}
}

You placed a loop over the collection inside of a loop over the collection. I’m not sure this is helping you?

I’m not familiar with this syntax for hasOwnProperty

I’m not sure how to separate properties without {property}: {source[property]} nor how to check every property. I found every online was a way to check each property and for in examples showed to use {property}: {source[property]}

I’m trying to loop through the source object and check if collection has all objects in source. This is my thought process and I’m not sure how to do it. I’ve been working 9am - 12pm on this and after have to move on to other work, I wish I could find a better strategy to solve these problems. 1 per day (at best) is really tough

hasOwnProperty('somePropertyName') checks if the object has a property matching the exact name in the string.

let person = {
  name: 'bob',
  pet: 'cat',
}

console.log(person.hasOwnProperty("pet")) // true
console.log(person.hasOwnProperty("pet: 'cat'")) // false

The above object has no property named pet: 'cat'. The value of the pet property is "cat".

So how would you check that the above person has a pet and that pet is a cat?

I’m checking the docs and I can’t see an example of such a situation. Would we just check each separately with two if statements?

if (person.hasOwnProperty("pet") {
 if(person.hasOwnProperty('cat')
} 

I’ve checked the docs and posts like this How to check if a value exists in an object using JavaScript - Stack Overflow but they’re not with such objects. I still don’t know how far off my last attempt was but I saw someone was using every also.

Is ({property}: {source[property]}) the only part I need to change?

How do you get the value associated with a property? If you get the value, then you chan check if it matches.

Yeah I’ve checked 10+ articles I’m not sure why I can’t figure it out. I’m just searching “how to get value of property js” would it be person.pet to get cat?

I found this

for (let [key, value] of Object.entries(person)) {
  console.log(value)
}

which returns bob and cat. But I’m not sure how this fits in with the problem. Can you tell me which parts I’m doing right and which is wrong? I’m a bit lost at this point

I’m not sure what articles you’re looking at.

let person = {
  name: 'bob',
  pet: 'cat',
}

console.log(person.hasOwnProperty("pet")) // true
console.log(person["pet"]) 

You need to check which elements of the array have the properties of the source object and those properties have the same value. To do so, you need to be able to access the values of these properties for each object in the array.

I will try to spimplify that for you. Let’s use alphabet letters.

First argument is an array of objects:

[{first: 'a', second: 'b', third: 'c'},
{first: 'a', third: 'f', last: 'z'},
{last: 'z'},
...]

if you write
arr[2] you will get
{last: 'z'} ← object.
Not string, not property, not value - OBJECT.

If you write arr[2].last you will get a value 'z' that was assigned to the property last.

You need to understand what is happening here first. Read about javascript array and object notation, understand object methods repeat earlier lessons, watch tutorials, you know the drill.
arr[1] is not the same as obj[1] - that is the important part.

Ok, now on to the second argument:

{first: 'a', third: 'c'}

Second argument is an object.
NOT an array.

You should know already how to get key name out of object and value that is assigned to that key.

Your job is to look at the second object, get its property names and values, then check if an object in the array (array at the beggining) have those property: value pairs.

Yes? Push it to an array.
No? Check the next one.
Finally return the array.

The first object matches both properties and values. You push it.
The second object matches properties, but values are different. You don’t push it
Third one doesn’t match properties, so also no push.

Array looks like:
[{first: 'a', second: 'b', third: 'c'}]
and we return it.

edit: better example
Hope that clarified anything. Objects vs arrays were confusing for me too.

@MyTrueName Ah yes I see what you mean by arr[2] vs arr[2].last

I went with this solution and have been studying it:

function whatIsInAName(collection, source) {
  let keys = Object.keys(source);
  //console.log(keys);
  return collection.filter(function(object) {
    for(let i = 0; i < keys.length; i++) {
      if (!object.hasOwnProperty(keys[i]) || object[keys[i]] !== source[keys[i]]) {
        return false;
      }
    }
  return true;
}); 
}
console.log(whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 9999, "c": 3}));

It seems I was far off, specially since it turns out I could ignore the “only change below this line”. I’ve been trying to explain each solution to myself after doing it (as they say you never know something unless you can explain it).

The only part I want to double check on is does the function (object) access objects in collection because it’s placed within in the filter method on collection? Lastly, object[keys[i]] and source[keys[i]] seems to be logging only the first 2 indexes (1,2 and 1, 9999), why is that?

Btw if anyone can solve it and show me the code with my original approach that’d be helpful.