I’ve been stuck on this Lab for the past few hours and have tried to accomplish it with multiple different paths (as you can see from all the commented out lines of code).
Ultimately I am unsure how I can properly validate if each object within the array contains all the respective properties & values of the source object. I attempted to store each property from the source object in an array, parse it, then see if each object element of the array includes it. However, this doesn’t take into account their values nor am I able to access each object specifically. At the moment I’m just parsing objects rather than their key/value pairs.
Your code so far
function whatIsInAName(objArr, sourceObj) {
// const filteredArr = objArr.filter(element => element.hasOwnProperty);
let filteredArr = [];
let count = 0;
/* for (let i = 0; i < objArr.length; i++) {
console.log("Object: " + i);
count = 0;
for (const element in objArr[i]) {
console.log("Property: " + element + "\n" + "Value: " + sourceObj[element]);
count++;
}
console.log("# of Key/Value Pairs: " + count);
console.log("\n");
} */
// filteredArr = objArr.filter(element => helperFunction(objArr, element, sourceObj) === true);
let sourceProperty = [];
for (const element in sourceObj) {
sourceProperty.push(element);
}
console.log(sourceProperty);
// Unable to use for-loop or if-else statements in the callback function due to token error
// .filter() takes 3 paramenters: current element, index of current element, and array it references
// Attempted to use index value for the objArr to access the properties of each object
filteredArr = sourceProperty.filter((element, index) => objArr[index].includes(element) === true);
return filteredArr;
}
/* function helperFunction(objArr, objElement, sourceObj) {
} */
console.log(whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 }));
This line of code represents my latest attempt at trying to solve this lab, but I am stuck.
Yeah, I went ahead and ensured it has a proper syntax. However, this approach leads me to a dead-end since it’s not technically validating the data. Only comparing the property names and extracting that value if they are.
let sourceProperty = [];
let objectProperty = [];
// Store properties of sourceObj in array
for (const element in sourceObj) {
sourceProperty.push(element);
}
// Store properties of objArr in a seperate arraay
for (const element of objArr) {
for (const prop in element) {
objectProperty.push(prop);
}
}
console.log("Source Object Properties:");
console.log(sourceProperty);
console.log("\n");
console.log("Object Properties:");
console.log(objectProperty);
filteredArr = sourceProperty.filter(element => objectProperty.includes(element) === true);
Ah, I see. I will do my best since I still haven’t found the right logic to utilize for this lab.
The main issue I am having is comparing the key/value pairs as a SINGLE entity rather than splitting the properties and values into two separate arrays to see if they are included in both the object element and source object. Or if there is a method to compare the object element as a whole that would also be suitable, but I don’t know how to implement that.
Iterate over the array containing objects as its elements.
Access the property within each element
Compare the property within each element to the property of the source object
If the two are equal then compare their key or value
If the two are not equal then skip over that element.
If the key/value is also equal then continue to parse over the rest of the key/value pairs for that object element.
If ALL key/value pairs are equal and the object element contains ALL key/value pairs from the source object then extract it into a new array.
If the key/value is not equal then skip over that element.
After parsing every object element from the original array go ahead and return the new array.
If no key/value pairs matched the source object then return an empty array.
do you need to iterate over the array? can’t you access the object directly?
what do you mean if the two are equal? what kind of comparison are you doing? isn’t there a way to check if an object has a property that is simpler than this?
Well, I wouldn’t know how many elements there will be in the array. Utilizing some form of loop to iterate over the array will ensure I am accounting for every object. Also to iterate over the object directly I would either have to reference its index or the object name, but it contained within an array without a name.
EX:for (const prop in objName) OR for (const prop in objArr[0])
If the object has a name such as:
const dog = {
name: “Sally”
};
I could then access it directly such as: for (const prop in dog)
As for what I meant in that step, I was checking if their property names are equal to each other.
EX:prop.name === sourceProp.name;
There is a simpler way to check if an object has a property, actually two I believe.
hasOwnProperty() I believe is the proper syntax
prop in object would be the alternative I think. ‘Prop’ being the property name itself and ‘object’ being the object name.
Iterate over the array of objects, so that I can access each individual object.
For each object inside the array, utilize the .hasOwnProperty()method to see if it includes the property from the source object.
NOTE: I won’t directly include this as a step since there may be fault in some logic, but this is the idea I currently have.
Utilize a for…in loop to parse over the properties of the source object which is nested within the loop used to iterate over the array of objects.
If the boolean value for the .hasOwnProperty()method is true then utilize a for…in loop to parse over the current element’s properties (from the array of objects).
Within the for…in loop utilize a condition to see if the value of the current property being parsed over in that object is equal to the value of the current property being parsed over in the source object.
If the two values are equal then push the object element from the array of objects into an array named newArray which will be used to return the array of objects that match.
If there are no matches then nothing will ever be pushed to the new array and an empty array will be returned.
const newArray = []; // Array to be returned
for (const element of objArr) {
for (const prop in sourceObj) {
if (element.hasOwnProperty(prop) === true) {
for (const prop in element) {
if (element[prop] === sourceObj[prop]) {
newArray.push(element);
}
}
}
}
}
I am aware that this Lab most likely expects a call-back function, but I had an idea in my mind and wanted to write it down before I forgot. So, using a .filter()callback function could also be employed which I can think of an approach for as well if the current one is faulty.
const newArray = []; // Array to be returned
let elementMatch;
for (const prop in sourceObj) {
for (const element of objArr) {
elementMatch = false;
if (element.hasOwnProperty(prop) === true) {
for (const arrProp in element) {
if (element[arrProp] === sourceObj[prop]) {
elementMatch = true;
}
}
}
if (elementMatch === true) {
newArray.push(element);
}
}
}
So, I added a variable that stores a boolean value and also swapped the inner/outer loops at the top. At the end of the iteration of the loop that parses over the objects in the array of objects, it will only push that object into the new array if the elementMatch remains true. I ensured there is a reset for the variable’s boolean value for each iteration, so each element gets a chance.
Okay, I appear to be getting closer. The commented out code is my first iteration and the second iteration has me swapping around the for-loop declarations. I also added a for-loop name, so that I could break out of an iteration if the element from the object array doesn’t have the element from the source object. I had issues where it would just iterate again if it didn’t have it, get to the property it DOES have, and then the elementMatch was made true. So, something like ‘bat’ was being added if the source object was looking for ‘apple’ and ‘bat’.
function whatIsInAName(objArr, sourceObj) {
const newArray = []; // Array to be returned
let elementMatch;
console.log("Array of Objects:");
console.log(objArr);
console.log("\nSource Object:");
console.log(sourceObj);
console.log("\n");
// console.log("Elements Added to New Array:");
/* for (const prop in sourceObj) {
console.log("Current Source Obj. Property:");
console.log(prop);
console.log("\n");
for (const element of objArr) {
elementMatch = false;
if (element.hasOwnProperty(prop) === true) {
for (const arrProp in element) {
if (element[arrProp] === sourceObj[prop]) {
elementMatch = true;
}
}
}
if (elementMatch === true) {
if (newArray.includes(element) === false) {
console.log("Element being added to new array:");
console.log(element);
console.log("\n");
newArray.push(element);
}
}
}
} */
for (const element of objArr) {
console.log("Current Object from Array:");
console.log(element);
console.log("\n");
objectLoop: for (const prop in sourceObj) {
elementMatch = false;
for (const arrProp in element) {
if (element.hasOwnProperty(prop) === true) {
if (element[arrProp] === sourceObj[prop]) {
elementMatch = true;
}
}
else {
break objectLoop;
}
}
}
if (elementMatch === true) {
if (newArray.includes(element) === false) {
console.log("Element being added to new array:");
console.log(element);
console.log("\n");
newArray.push(element);
}
}
}
console.log("\n");
return newArray;
}
console.log(whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 }));
Console Output:
Array of Objects:
[ { apple: 1, bat: 2 },
{ bat: 2 },
{ apple: 1, bat: 2, cookie: 2 } ]
Source Object:
{ apple: 1, bat: 2 }
Current Object from Array:
{ apple: 1, bat: 2 }
Element being added to new array:
{ apple: 1, bat: 2 }
Current Object from Array:
{ bat: 2 }
Current Object from Array:
{ apple: 1, bat: 2, cookie: 2 }
Element being added to new array:
{ apple: 1, bat: 2, cookie: 2 }
[ { apple: 1, bat: 2 }, { apple: 1, bat: 2, cookie: 2 } ]
Now I’m only failing two test cases which account for empty arrays.