Object search works first time only - javascript

I created an object called "Jarz". Then added an object within it called 'cat'. Then I made a function to search within the Jarz object for an object called 'cat', which works. However for every object after 'cat' that I add to 'Jarz' the function will not find it in the search. Only the first run ever works. Here is the code:
var Jarz = {};
Jarz['cat'] = {};
Here is the function:
function doesObjExist(ObjName){
var tmpArr = Object.keys(Jarz);
for(var i = 0; i < tmpArr.length; i++){
if(tmpArr[i] === ObjName){
return true;
}
else {
return false;
}
}
}
When I run it on the first object 'cat' it returns true. But any obj I make after that returns false. ie:
Jarz['hat'] = {};
doesObjExist('hat') // returns false
I cant seem to find what is missing here. Any help is appreciated, thanks.

Its because when you call it with hat,it is checking first for cat as it is false your returning from the loop so it wont execute further to check for hat
change this to
var Jarz = {};
Jarz['cat'] = {};
console.log(doesObjExist('cat'));
Jarz['hat'] = {};
console.log(doesObjExist('hat'));
function doesObjExist(ObjName) {
var tmpArr = Object.keys(Jarz);
var count = 0;
for (var i = 0; i < tmpArr.length; i++) {
if (tmpArr[i] === ObjName) {
return true;
} else {
count++;
}
}
if (count >= tmpArr.length)
return false;
}
Hope this helps

Related

How to make this removeMiddle test pass when just return 1 value

I am trying to create a function to make this test pass
Here is my following code for my test cases:
var removeMiddle = require("./remove-middle");
test("Remove middle", function () {
var words = ["mouse", "giraffe", "queen", "window", "bottle"];
var expectedWords = ["mouse", "giraffe", "window", "bottle"];
var expectedOutput = ["queen"];
var output = removeMiddle(words);
expect(output).toEqual(expectedOutput);
expect(words).toEqual(expectedWords);
});
Here is my function that I created:
function removeMiddle(words) {
let index = [];
words.splice(2, 1);
for (let i = 0; i < words.length; i++) {
if (words[i] === "queen") {
index.push(words[i]);
}
}
return words;
}
module.exports = removeMiddle;
Right now my function just passed the second test case which is: expect(words).toEqual(expectedWords);
Firstly, you expect your output to be the word(s) removed. But you are returning the words array from removeWords. You probably can return index.
Also, once you have spliced your words array, queen will no more be a part of the array. So your for loop does nothing and index returns an empty array.
You can modify your code like this to get your expected output:
function removeMiddle(words) {
let index = [words[2]];
words.splice(2, 1);
return index;
}
But right now your code is a little hard coded, works only for a fixed length of array(5). You can do the following if you want a more generic solution.
function removeMiddle(words) {
if(words.length == 0) return [];
let index = [];
let middleElements = [];
if(words.length % 2 == 0){
console.log(words[Math.floor(words.length/2)]);
middleElements.push(words[Math.floor(words.length/2)]);
words.splice(words.length/2,1);
console.log(words[Math.floor(words.length/2)]);
middleElements.push(words[Math.floor(words.length/2)]);
words.splice(words.length/2,1);
}
else{
console.log(words.length/2);
middleElements.push(words[Math.floor(words.length/2)]);
words.splice(words.length/2,1);
}
return middleElements;
}

I need help figuring out why I'm getting NaN in this function

function multipleLetterCount(str){
var finalObj = {};
for(var i = 0; i < str.length; i++){
if(!str[i] in finalObj){
finalObj[str[i]] = 1;
} else {
finalObj[str[i]]++;
}
}
return finalObj;
}
console.log(multipleLetterCount("SomeWord"));
I need help figuring out why the values are coming up as NaN. Thanks
why the values are coming up as NaN
str[i] represents different character in each iteration. When you negate that character like !str[i] that becomes false. Hence the condition (if(false in finalObj)) is always false and executes only the else part. At this point finalObj[str[i]] is undefined. Finally, incrementing undefined (undefined++) gives you NaN.
Try with Object.prototype.hasOwnProperty() which returns a boolean indicating whether the object has the specified property as its own property:
function multipleLetterCount(str){
var finalObj = {};
for(var i = 0; i < str.length; i++){
if(!finalObj.hasOwnProperty(str[i])){
finalObj[str[i]] = 1;
} else {
finalObj[str[i]]++;
}
}
return finalObj;
}
console.log(multipleLetterCount("SomeWord"));
Note that there are a plethora of ways to resolve the problem, all of which depend on how robust you need your function to be.
For simplicity, instead of if(!str[i] in finalObj), do if (!(str[i] in finalObj)).
You can simplify your code like this
function multipleLetterCount(str){
var finalObj = {};
for(var i = 0; i < str.length; i++){
if (finalObj[str[i]]) {
finalObj[str[i]]++;
} else {
finalObj[str[i]] = 1;
}
}
return finalObj;
}
console.log(multipleLetterCount("SomeWord"));
How about?
let string = 'SomeWord';
const result = string.split('').reduce((a, b) => {
a[b] ? a[b]++ : a[b] = 1
return a;
}, {});
console.log(result);

Javascript foreach not executing for all objects

I currently have an object that adds itself to an array whenever a new one is created. Eventually, I want to remove all of the references in the array so I can add new ones.
I've created an object method (this.removeFromArray()) that looks for itself in the array and splices itself out. removeAll() runs a for loop that makes each object in the array run removeFromArray(), so I expect that when I try to read out the items in the array, I should get nothing.
Instead, depending on the amount of objects created, I get one or two left behind. How can I fix this and have all objects in the array cleared out?
var objArray = [];
function obj(name) {
objArray.push(this);
console.log("Created "+name);
this.name = name;
this.removeFromArray = function() {
objArray.splice(
objArray.findIndex(function(e) {
return e == this;
}),
1
);
}
}
function removeAll() {
for (var i = 0; i <= objArray.length - 1; i++) {
objArray[i].removeFromArray();
}
}
var foo = new obj("foo");
var bar = new obj("bar");
var cat = new obj("cat");
var dog = new obj("dog");
var bird = new obj("bird");
removeAll();
for (var i = 0; i <= objArray.length-1; i++) { //Check the values in the array for leftovers
console.log(objArray[i].name);
}
//Expected nothing in the console but the creation messages, got foo and bar instead
If you want to simply delete all the created object, edit removeAll() function like below:
Note that you have to create a variable for objArray.length, not directly put the objArray.length to for() loop.
function removeAll() {
var len = objArray.length;
for (var i = 0; i <= len - 1; i++) {
objArray.splice(0,1);
}
}
better way to achieve this would be to utilize inheritance through prototype. it is better than creating a function inside the constructor object.
var objArray = [];
function Obj(name) {
this.name = name;
objArray.push(this);
}
Obj.prototype.removeFromArray = function() {
var i = -1,
len = objArray.length,
removed = null;
while (++i < len) {
if (objArray[i] === this) {
removed = objArray.splice(i, 1);
removed = null; //nullify to free memory, though not that necessary
break;
}
}
};
Obj.prototype.removeAll = function() {
var len = objArray.length,
removed = null;
//note that i started from the last item to remove to avoid index out of range error
while (--len >= 0) {
removed = objArray.splice(len, 1);
removed = null; //nullify to free memory, though not that necessary
}
};

making nested objects array and checking if the key exists in objs

I am trying to check if the keys exits in array of objects. I am getting false each time when I pass existing key to my function.
var connect_clients = [];
connect_clients.push({
'a': val
});
function lookup(name) {
for (var i = 0, len = connect_clients.length; i < len; i++) {
if (connect_clients[i].key === name)
return true;
}
return false;
}
console.log(lookup('a'));
Is there anything wrong?
connect_clients[i].key refers to the actual property named key, not the keys of the object.
For this case, you can use Object.keys to get an array of keys of an object and use Array.prototype.some to make sure that at least one of the objects has the key. For example,
function lookup(name) {
return connect_clients.some(function(client) {
return Object.keys(client).indexOf(name) !== -1;
});
}
Use Object.keys() to get keys of an object.
var val = 'val';
var connect_clients = [];
connect_clients.push({
'a': val
});
function lookup(keyName) {
var i;
for ( i = 0; i < connect_clients.length; i++) {
var keys = Object.keys(connect_clients[i]);
if(keys.indexOf(keyName) !== -1) {
return true;
}
}
return false;
}
console.log(lookup('a'));

Storing closure functions within array using loop

This is the code :
i'm storing the function body inside each element of "resultArr"
, the problem is when i call the stored function _class[0]()i can't reach the exact i it's always 4 !
var checkAttendanceFunc = function(nameArr) {
var resultArr = [];
for(var i = 0; i < nameArr.length; i++) {
resultArr.push(function(){console.log('Is', nameArr[i], 'present?', i);});
}
return resultArrultArr;
};
var _class = checkAttendanceFunc(["alex", "brownex", "chris", "mack"]);
i think it's obvious if i call any item of _class i.e _class[0]() the index will be 4 and the name will be "undefined"
So how wan i solve this problem, i saw some ppl use the apply native function, but i think it works only if we store the function name not the body of a given function
In this case, all the closures inside checkAttendanceFunc point to a reference of the i and nameArr variable.
When the loop is done, i's value is 4 for all the functions you generated, what you need is copying i each time you pass it to a closure.
There are several ways for you to achieve this:
Immediately call the function
var checkAttendanceFunc = function(nameArr) {
var resultArr = [];
for(var i = 0; i < nameArr.length; i++) {
resultArr.push(function(index){
return function(){
console.log('Is', nameArr[index], 'present?', index);
}
}(i));
}
return resultArr;
};
Here you're passing an argument fo the closure and you call it immediately. In this case, i is getting copied and the function has its own value named index.
Use another function that iterates on the array
In this case I'm using Array.forEach
var checkAttendanceFunc = function(nameArr) {
var resultArr = [];
nameArr.forEach(function (value, index){
resultArr.push(function() {
console.log('Is', value, 'present?', index);
});
});
return resultArr;
};
In this case the functions created recieve a copy of value and index, which means they will always point to the same values.
Still not sure I understand the intent of this code, but here's a working version that does what I think you're trying to do:
var students = ["alex", "brownex", "chris", "mack"];
var _class = students.map(function(name, i) {
return function() {
console.log('Is', name, 'present?', i);
};
});
See it in action here.
If you're really just looking for how to make it work with a for-loop, you could always capture it like this:
var checkAttendanceFunc = function(nameArr) {
var resultArr = [];
for(var i = 0; i < nameArr.length; i++) {
resultArr.push((function(idx) {
return function() {
console.log('Is', nameArr[idx], 'present?', idx);
};
})(i));
}
return resultArr;
};
var _class = checkAttendanceFunc(["alex", "brownex", "chris", "mack"]);
Similarly, you can also use .bind():
var checkAttendanceFunc = function(nameArr) {
var resultArr = [];
for(var i = 0; i < nameArr.length; i++) {
resultArr.push((function(idx) {
console.log('Is', nameArr[idx], 'present?', idx);
}).bind(null, i));
}
return resultArr;
};
var _class = checkAttendanceFunc(["alex", "brownex", "chris", "mack"]);
Either way, I personally find the .map() solution much more elegant and readable.

Categories

Resources