I am able to get values from both but do not know how to check if one’s value set exists in other …
But to my disappointment when i saw hint despite there is no mention of hind all 3 solutions use filter , now i still cannot understand it …Is there no other way in javascript to loop using a for loop and find if an object has values that we want and give us out put …
Kindly guide… I ask as i do not want to cram up the solution and then change my thinking as per solution but have my own solution …
Adding my jsfiddle code for convinience–
////////////-----------------------------------
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
for (var key in collection){
if(collection.hasOwnProperty(key)){
console.log(collection[key]);
}
}
// Only change code above this line
return arr;
}
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
////////------------------------------------------------
Just a little bit of help to see if you can understand … and let you create your own solution with for loops … i used for loop probably as i didnt know filters at the time.
for (var key in collection[0]) {
console.log(collection[0][key]);
console.log(key)
}
for(var i = 0; i < collection.length;i++){
var src = source[key];
for (var key in collection[i]) {
if(collection[i][key]===source[key]){
arr.push(collection[i]);
// console.log(arr);
}
}
}
Now 2 conditions are satisfied, will get back to you soon …
@JohnL3 - Hi , i am really stuck at not being able to loop through in case of more then one property value in the object source - like here - { “a”: 1, “b”: 2 }
So if there is one value like - { “a”: 1 } i made some changes to code you have suggested and it works , but i tried using .hasOwnPropety etc and its not giving right results- my current code is here - can you please guide as to what i can do to be able to compare more then one property value …
Thanks
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++){
var src = source[key];
for (var key in collection[i]) {
if(collection[i][key]===source[key]){
arr.push(collection[i]);
// console.log(arr);
}
}
}
// Only change code above this line
return arr;
}
whatIsInAName([{ "a":
@honmanyau - thanks , so where i be using this , like here -
I am using this right now -
for(var i = 0; i < collection.length;i++){
var src = source[key];
for (var key in collection[i]) {
if(collection[i][key]===source[key]){
arr.push(collection[i]);
// console.log(arr);
}
}
}
So i tried using it like -
for (var key in collection[i]) {
if(Object.keys(collection)===Object.keys(source)){
but its not giving any results, i am really sorry but i am very new to this ...
Regards
Don’t forget the power of proper indentation when showcasing code and you have a single line that I have commented-out below which would cause error based on the code you pasted. Sorry I don’t have the full solution for you but I hope this helps a little
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++){
//Key is not defined at this point so it would break the application
//Remove this line:
//var src = source[key];
for (var key in collection[i]) {
//This statment says that if any of the keys match then add it to the result array.
//The problem definition states that all keys must match.
//This is why the code that you have passes the first two test
//cases where there are no objects that contain a partial result.
if(collection[i][key]===source[key]){
arr.push(collection[i]);
}
//Instead you need to only push items to the array when all of the attributes
//in the source match attributes in the collection
}
}
// 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 });
@HassanM - thanks for this amazing reply , i am however still confused at one point -
for(var i = 0; i < collection.length;i++){
var src = source;
for (var key in collection[i]) {
if(collection[i]===src){
arr.push(collection[i]);
}
}
}
If i am doing console.log(collection[i]); it gives value of each object from index 0 onwards, same way if i use console.log(source) it gives values of source object , but when i am comparing it here , its returning an empty array…
Is this the right way to compare 2 objects … and if not this slight change of comparing collection[i] and src, why is it not working , src is the variable that holds source …
@jinisner There are some problems with your code snippet:
You are right, this is not the right way to compare two objects because you are not comparing the value of the objects. Instead the default equal operator(== & ===) in JavaScript will only return true if both objects refer to the same location in memory. Which in your case they are not.
An example would be:
var x = {};
var y = {};
var z = x;
x === y; // => false
x === z; // => true
The other thing is that the logic you are trying to do is wrong, {a:1, b:2 }, {a: 1} => this should be added to the final list even though they are not exactly equal. The question says that everything in the source is available in the collection. This makes it easier for you.
Why does it make it easier? Because you only have to iterate over the keys of the source and fetch that from each object on the collection and see if it matches the value of the corresponding key in the source. if it returns undefined then you know its not there if it return a value then you check that.
P.S. Press on with Object.Keys, iterate over all keys and try and translate what I said to code first and then have a read in Stackoverflow about it all.
@HassanM Just beat me to it with an excellent response. I thought I’d still post what I typed particularly because of the second code example, which may save you time in the future.
The problem here is that you can’t you can’t simply compare two object literals like that in Javascript. Consider that you have two boxes, one box has an apple and an orange inside it; the other box has an apple in it. The two boxes are clearly different—just as {a: 1, b: 2} is clearly different to {a: 1}, and therefore {a: 1, b: 2} === {a: 1} will return false.
In fact, in Javascript the following will also return false:
const nya = {a: 1};
const nyu = {a: 1};
console.log(nya === nyu); // false
This is because the objects are placed in different parts of the computer’s memory and nya and nyu are references to them.
It may be clearer if you consider the following example:
I think it may be worthwhile forgetting about the code you have written for a while, and take some time to think about the logic, by breaking the problem into smaller steps that you can digest, behind whatever code you are going to write. Try [[{a: 1}], {a: 1}], [[{a: 1, b: 2}], {a: 1}], [[{a: 1}], {a: 1, b: 2}] and [[{a: 1, b: 2}], {a: 1, b: 2}] first.
@HassanM , @honmanyau - As has been suggested i went through the code from start and studies Object.keys() , Object , after the that i was able to find the values and keys separately like here –
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
for(var i = 0; i < collection.length;i++){
for(var key in collection[i]){
console.log(collection[i][key]);
console.log(Object.keys(collection[i]));
}
}
console.log(source);
console.log(Object.keys(source));
// 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 });
But i have no clue as to how i can use the info as i do not think that arrays can be compared like strings, is this the right way to proceed or am i doing something wrong here …
ForEach currentKeyFromSource in Object.keys(Source) => Check does current Object in collection match the following:
Collection[i][currentKeyFromSource] === Undefined => this means this Object in the collection does not have the item. If this is false then we can check the next thing.
Collection[i][currentKeyFromSource] === Source[currentKeyFromSource] => we are checking the value now do they match great we can carry on looping. If they don’t lets break out of the loop no need to check any more but its too early to add it to the result because it needs to match each key from the Source.Keys.
Can you now think who should be in the outer loop? We don’t care that all props in the collection objects match its the other way around.
@HassanM - So the task wants me to find out if inside an array of objects if there are any objects that contain a certain property value pair/pairs…
But if i do not want to use filter function , i can get the values but cannot compare them as object cannot be compared as strings, same way even if i get them returned as arrays , i still am not able to find a way to loop inside collection and check for values similar to that of source …
You have a clear understanding so it must be real easy for you but here when you say -
ForEach currentKeyFromSource in Object.keys(Source)
Do you mean - Object.keys(source) which returns array - Array [ “a”, “b” ]
Then when you say Collection[i][currentKeyFromSource] this returns
Try the following code where you take collection[1][“a”] this will return two thing either the value of “a” or undefined if the object in the collection does not have that property defined. Now you can take that check and put it inside the for loop over source keys and I think that is your solution. Just remember everything in source has to match not just a single property.
Please don’t apologise about, its really normal to find these kinds of problems really challenging I struggle plenty as well.
Best Regards,
P.S. Filter is not a magic bullet it just iterates over the array. Try solving it with Filter and then translate that.
@HassanM - i have tried as you are saying and per me it should give result but is not -
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
for(var key in collection){
if(collection[key] != undefined){
for(var key in source){
if(Collection[i][key] === Source[key]){
arr.push(collection[i]);
}
}
}
}
console.log(arr);
// 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 });
So what i am doing is creating a collection of keys of both collection and source and then trying to compare if its not undefined still its now saying collection is not defined …where i am wrong can you please suggest
//You need something more like:
for(var key in Object.keys(source)){
for(var obj in collection){
//Check if obj has the property with name key and then
//that the value of both source and obj match for the same key.
}
}
@JohnL3 - thanks for the code, however at line 17 i am unable to understand as to how -
if(objA[testKey] === test[testKey])
where in the task case an array of [“a”,“b”] can be compared here, i tried to use the logic till this point and came up with the below code , i am now getting 2 condition satisfied , but where there are more then 2 key-value pair in source its not working
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
var testkey = Object.keys(source);
for(var i = 0; i < collection.length; i ++){
if( collection[i].hasOwnProperty(testkey)){
if(collection[i][testkey] === source[testkey]){
arr.push(collection[i]);
}
}
}
console.log(arr);
// 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 });
for(var i = 0; i < collection.length; i ++){
if( collection[i].hasOwnProperty(testkey[0])){
if(collection[i][testkey[0]] === source[testkey[0]]){
arr.push(collection[i]);
}
}
}
Your getting closer … look at what i changed to what you supplied … testKey to testkey[0] …
testKey is array of keys … as my example had only one key i just used testKey … but if more than one key you have to use testKey[0] etc … change your above code and use testKey[0] … then use testKey[1] and see your results
you will then realize you need one more step … eg you need to loop through testKey as well as loop through collection so instead of having testKey[0] you can have testKey[x] …
edit looked at my solution and realize still more to be done but if you get this done can worry about that then