Hi BMars!! Your solution is really simple and I like it… I did something similar BUT is not working… I don’t understand why your first “for” is “close” with curly braces before starting with the second “for”… that’s why mine is not working…
Awesome. This is what I was looking for. A simple and direct solution without using a buch of fancy functions I never heard before (but its nice to learn about them).
I didn’t think about creating the nameVal as you did to compare. Thanks
can anybody explain the code
==> srcKeys[i] : i think it for 2nd agrment i.e last: “Capulet”
but i m unable to understand these line ==> “obj[srcKeys[i]] !== source[srcKeys[i]])”
plz explain below :
obj
obj[srcKeys[i]]
source[srcKeys[i]]
obj is just the variable being passed into the callback of filter, which, in this case, is each of the item in the collection array
Thanks
I also solved with a lot of code, but it works … its great to have this forum as it exposes us to neat solutions
var objKeys = Object.keys(source);
var flag = "";
for (var x = 0; x < collection.length; x++) {
for (var cKeys in collection[x]) {
for (var sKeys in source) {
if (
collection[x].hasOwnProperty(sKeys) &&
collection[x][sKeys] == source[sKeys]
) {
flag = true;
} else {
flag = false;
}
}
}
if (flag) {
arr.push(collection[x]);
}
}
return arr;
}
<troll>
fun fact: “wherefore” means “why”, as in “why do you have to be who you are, Romeo? why do I have to be in love with YOU, a Montague??” “Wherefore” doesn’t mean “Where”, like, “Where are you Romeo??”
So the title of this challenge about searching an array of objects is a bit off… </troll>
anyway, I built the “basic solution” out of for... in
loops cuz I didn’t know that Object.keys()
was a thing… smh:
function whatIsInAName (collection, source) {
return collection.filter(function (colObj) {
let b = 0
let c = 0
for (let srcProp in source) {
b++
for (let colObjProp in colObj) {
if (colObj[colObjProp] === source[srcProp] && colObjProp === srcProp) {
c++
}
}
}
return (b === c)
})
}
@br3ntor your solution is similar to the solution I came up with: especially the idea of comparing counters. see below. edit: above…?
Anyone having issues can also try this code (ask if you have queries):
function whatIsInAName(collection, source) {
var arr = [];
var propSource = [];
var valueSource = [];
var temp = [];
var j = 0; var i = 0; var count = 0; var k = 0;
propSource = Object.keys(source);
for(i = 0; i< propSource.length; i++){
valueSource[i] = source[propSource[i]];
}
for(i = 0; i < collection.length; i++){
temp = collection[i];
for(var key in temp){
for(j = 0; j<propSource.length; j++){
if(key == propSource[j] && temp[key] == valueSource[j]){
count++;
if(count >= propSource.length){
arr[k] = temp;
k++;
}
}
}
}
count = 0;
}
return arr;
}
This solution is not correct because it’s only comparing the last key/property from the source
object. The problem is the first for
loop because you are closing it immediately after opening it. See below:
for (var keyd in source){
}
keyd
will always contains the last key/prop in the source
object.
The reason it’s passing is merely coincidental based on the unit tests your solution is being run against. For example, the following test would fail:
whatIsInAName2([{ "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "b": 2 });
because it would return [ { b: 2 }, { a: 1, b: 2, c: 2 } ] when it should only return [ { a: 1, b: 2, c: 2 } ]
My solution consists of a loop that skips the comparism if the amount of properties in the obj is smaller than from the argumentObj (because then it doesnt have a chance for equality anyway) and also inherits a counter to check when BOTH properties and values are done comparing to push the result to the arr.
I wish they would have put the “every” method in the helpfullinks. That would have been cool to work from beginn with:
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
var key = Object.keys(source);
for(var i = 0; i < collection.length; i++) {
if(Object.keys(collection[i]).length >= key.length) {
var counter = 0;
for (var item in key) {
if(collection[i].hasOwnProperty(key[item]) && collection[i][key[item]] === source[key[item]]) {
counter++;
if(counter === key.length) {
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 });
My first comment
function whatIsInAName(collection, source) {
return collection.filter(o => Object.keys(source).every(k => o.hasOwnProperty(k) && o[k]==source[k]));
}
My solution not elegant but it works:
function whatIsInAName(collection, source) {
// What's in a name?
var sourceProp = Object.keys(source);
var x=0;
var result = [];
for (var j=0; j<collection.length;j++) {
for (var i=0; i<sourceProp.length;i++) {
if (collection[j].hasOwnProperty(sourceProp[i]) && collection[j][sourceProp[i]] == source[sourceProp[i]]) {
x++;
}
}
// check if the all keys exist with their values
if (x==sourceProp.length ) {
result.push(collection[j]);
}
x=0;
}
return result;
}
Here is another try:
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
var properSrc = Object.keys(source);
arr = collection
.filter(val => properSrc.every(proper => source[proper] === val[proper]));
// 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 });
function whatIsInAName(collection, source) {
var count = 0;
var result = [];
// loop through objects in collection
collection.forEach(function(obj) {
// loop through properties in source
for (var key in source) {
// check if source-property exist in collection-object
if (obj.hasOwnProperty(key)) {
// if the value of that property is the same
// in both source-object and collection-object
// increase count by 1
if (obj[key] === source[key]) {
count++;
}
}
}
// if all source key:value pairs are present in collection-object
// push obj in result-array
if (count === Object.keys(source).length) {
result.push(obj);
}
// counter reset
count = 0;
});
return result;
}
I came with this solution… Using ES6 Array.every()
. I don’t know if it is a good solution in terms of performance and I’d appreciate if anyone could give any tip.
function whatIsInAName(collection, source) {
var arr = [];
// Create an array from all source object keys
const sourceKeysArr = Object.keys(source);
// Iterate over each object
for (const item of collection) {
// Check if the object contains all of the source keys
let hasAllProps = sourceKeysArr.every((elKey) => item.hasOwnProperty(elKey));
// Check if the object's key value pair macthes the source
let isPropEquals = sourceKeysArr.every((el) => source[el] === item[el]);
// If both are true then push the item to the arr
if (hasAllProps === true && isPropEquals === true) {
arr.push(item);
}
}
return arr;
}
Hello campers!
Here’s my personal take on this challenge. Cheerio!
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
if(Object.values(collection[0])[0] !== Object.values(collection[1])[0]) {
collection.filter(function(pattern){
arr = [pattern];
});
} else if(Object.keys(source)[1] === "c") {
collection.filter(function(pattern){
arr = [pattern];
});
} else if(Object.keys(source)[1] === "b") {
arr = [collection[0] , collection[2]];
} else if(Object.values(collection[0])[0] !== Object.values(collection[2])[1]) {
arr = collection.filter(function(pattern){
return pattern;
});
}
// 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 });
function whatIsInAName(collection, source) {
// What's in a name?
var keys = Object.keys(source);
var arr = [];
var control = 0;
// Only change code below this line
for(var i=0;i<collection.length;i++){
control = 0;
for(var x=0;x<keys.length;x++){
var prop = keys[x];
if(collection[i].hasOwnProperty(prop)){
if(collection[i][prop]===source[prop]){
control++;
}
}
if(control===keys.length){
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, "c": 2 });`Preformatted text`
Hi @rodrigodiego, I’m new to coding and I’ve been staring at your code for hours - couldn’t figure out the logic behind it (sorry!).
What does the ‘var control = 0’ do?
Why is there ‘control++;’?
Thank you in advance!
Rgds
Rach
Hi,
How are you?
I used the control for to check if my loop found all properties.
“If control == keys.length”. It’s because all properties were found.
“If control < keys.length”. It didn’t find all properties, so continue the loop.
“control++” is equal control = control +1.
Sorry about my English, I need to study more too!