My api response looks like this:
id: (...)
user_id: (...)
symptoms: "Sore throat, Headache"
id: (...)
user_id: (...)
symptoms: "Anorexia (Loss of appetite), Shortness of breath (Difficult in breathing), Myalgias (Muscle pains), Sore throat, Headache"
I am trying to match a users symptoms to existing symptoms categories. A user can have upto 14 symptoms. I keep getting an error of Cannot read property 'slice' of undefined when i split and slice the array to get individual symptoms and match them.
When i try to put a default value for the object if a user has less than 14 symptoms, the error persists.
My code:
getSymNum (symp, c) {
var counter = 0
for (var xc in c) {
var symp1 = c[xc].symptoms.split(',')[0]
var symp2 = c[xc].symptoms.split(',')[1].slice(1)
var symp3 = c[xc].symptoms.split(',')[2].slice(2)
var symp4 = c[xc].symptoms.split(',')[3].slice(3)
var symp5 = c[xc].symptoms.split(',')[4].slice(4)
var symp6 = c[xc].symptoms.split(',')[5].slice(5)
if (symp3 !== undefined){
console.log("hello ha")
}
if (symp1 === symp) {
counter++
} else if (symp2 === symp) {
counter++
} else if (symp3 === symp) {
counter++
} else if (symp4 === symp) {
counter++
} else if (symp5 === symp) {
counter++
} else if (symp6 === symp) {
counter++
}
}
return counter
},
You can optimize the check by using array/string methods like contains() or indexOf():
etSymNum (symp, c) {
var counter = 0
for (var xc in c) {
if(c[xc].symptoms.indexOf(symp) !== -1){
counter++;
}
}
return counter
},
Alright Stackoverflow first post here. I am at a loss, and would appreciate any help.
I have a recursive function that seems to be working properly up until I try and return from it. (Just a little maze runner for fun)
When reaching the return statement it seems to loop back to the if(grid[y+1][x] ===2) statement.
Then I don't see the function getting called again, but the values for y and x start changing as it loops around the function before getting to the else at the bottom and returning there.
I also see the "inside return if" in the console, and setting break points in the browser shows the return statement gets called, just doesn't exit the function.
Many thanks in advance!!!
const grid =[0,0,0,0,3,2],
[0,0,0,0,3,0],
[0,0,0,0,3,0],
[3,3,3,3,3,0],
[0,0,0,0,0,0],
[1,3,3,3,3,3]
],
const recursiveSearch = (y, x) => { // init values y=5 x=0
console.log(y + ' ' + x);
if(grid[y-1]){
if(grid[y-1][x] === 0) {
grid[y-1][x] = 4;
recursiveSearch(y-1, x);
}
if(grid[y-1][x] === 2) {
console.log('inside return if');
return 'end point found at';
}
}
if(grid[y][x+1] || grid[y][x+1] === 0) {
if(grid[y][x+1] === 0) {
grid[y][x+1] = 4;
recursiveSearch(y,x+1);
}
if(grid[y][x+1] === 2) {
return "end point found at";
}
}
if(grid[y+1] || grid[y+1] === 0) {
if(grid[y+1][x] === 0) {
grid[y+1][x] = 4;
recursiveSearch(y+1,x);
}
if(grid[y+1][x] === 2) {
return "end point found at";
}
}
if(grid[y][x-1] || grid[y][x-1] === 0 ) {
if(grid[y][x-1] === 0) {
grid[y][x-1] = 4;
recursiveSearch(y,x-1);
};
if(grid[y][x-1] === 2) {
return "end point found at";
}
} else {
return "No solution found"
}
};
you must return value of calling recursive function.
const grid =[0,0,0,0,3,2],
[0,0,0,0,3,0],
[0,0,0,0,3,0],
[3,3,3,3,3,0],
[0,0,0,0,0,0],
[1,3,3,3,3,3]
],
const recursiveSearch = (y, x) => { // init values y=5 x=0
console.log(y + ' ' + x);
if(grid[y-1]){
if(grid[y-1][x] === 0) {
grid[y-1][x] = 4;
return recursiveSearch(y-1, x); // must return value of calling recursiveSearch
}
if(grid[y-1][x] === 2) {
console.log('inside return if');
return 'end point found at';
}
}
if(grid[y][x+1] || grid[y][x+1] === 0) {
if(grid[y][x+1] === 0) {
grid[y][x+1] = 4;
return recursiveSearch(y,x+1); // // must return value of calling recursiveSearch
}
if(grid[y][x+1] === 2) {
return "end point found at";
}
}
if(grid[y+1] || grid[y+1] === 0) {
if(grid[y+1][x] === 0) {
grid[y+1][x] = 4;
return recursiveSearch(y+1,x); // must return value of calling recursiveSearch
}
if(grid[y+1][x] === 2) {
return "end point found at";
}
}
if(grid[y][x-1] || grid[y][x-1] === 0 ) {
if(grid[y][x-1] === 0) {
grid[y][x-1] = 4;
return recursiveSearch(y,x-1); // must return value of calling recursiveSearch
};
if(grid[y][x-1] === 2) {
return "end point found at";
}
} else {
return "No solution found"
}
};
Kindly add return statement for every recursive call.
My js/jquery function does not work properly and instead of INT returns undefined.
function __getLastSelectedCategory(table_id) {
if ( jQuery('.categories_table[data-table-id="1"]').find('td.active').length > 0 ){
console.log('check1');
if (table_id != '0') {
console.log('check2');
var checkTableId = parseInt(table_id) - 1;
var table = jQuery('.cl_categories_display ').find('table[data-table-id="' + checkTableId + '"]');
if (table.find('td.active').length > 0) {
console.log('check3');
console.log('table id: ' + table.find('td.active').data('category-id'));
return table.find('td.active').data('category-id');
} else {
console.log('check4');
__getLastSelectedCategory(checkTableId);
}
} else {
console.log('check5');
var lastTable = jQuery('.cl_categories_display ').find('table:last');
var lastTableId = lastTable.data('table-id');
if (lastTable.find('td.active').length > 0) {
console.log('check6');
return lastTable.find('td.active').data('category-id');
} else {
console.log('check7');
__getLastSelectedCategory(lastTableId);
}
}
} else {
console.log('check8');
return null;
}
}
when I run this function I see in console:
check 1
check 5
check 7
check 1
check 2
check 3
table id: 1
last cat: undefined
so the recursion works fine, but instead of integer (console printed "table id: 1") ir returns undefined. What could be wrong?
You forgot return from recurse call: It returned value from the inner function to the outer, but did not return it from outer function to the caller. Try this:
function __getLastSelectedCategory(table_id) {
if ( jQuery('.categories_table[data-table-id="1"]').find('td.active').length > 0 ){
console.log('check1');
if (table_id != '0') {
console.log('check2');
var checkTableId = parseInt(table_id) - 1;
var table = jQuery('.cl_categories_display ').find('table[data-table-id="' + checkTableId + '"]');
if (table.find('td.active').length > 0) {
console.log('check3');
console.log('table id: ' + table.find('td.active').data('category-id'));
return table.find('td.active').data('category-id');
} else {
console.log('check4');
return __getLastSelectedCategory(checkTableId);
}
} else {
console.log('check5');
var lastTable = jQuery('.cl_categories_display ').find('table:last');
var lastTableId = lastTable.data('table-id');
if (lastTable.find('td.active').length > 0) {
console.log('check6');
return lastTable.find('td.active').data('category-id');
} else {
console.log('check7');
return __getLastSelectedCategory(lastTableId);
}
}
} else {
console.log('check8');
return null;
}
}
Given the following obj:
var inputMapping = {
nonNestedItem: "someItem here",
sections: {
general: "Some general section information"
}
};
I'm writing a function to get that data by passing in a string "nonNestedItem" or in the nested case "sections.general". I'm having to use an eval and I was wondering if there was maybe a better way to do this.
Here is what I have so far and it works okay. But improve!
function getNode(name) {
var n = name.split(".");
if (n.length === 1) {
n = name[0];
} else {
var isValid = true,
evalStr = 'inputMapping';
for (var i=0;i<n.length;i++) {
evalStr += '["'+ n[i] +'"]';
if (eval(evalStr) === undefined) {
isValid = false;
break;
}
}
if (isValid) {
// Do something like return the value
}
}
}
Linky to Jsbin
You can use Array.prototype.reduce function like this
var accessString = "sections.general";
console.log(accessString.split(".").reduce(function(previous, current) {
return previous[current];
}, inputMapping));
Output
Some general section information
If your environment doesn't support reduce, you can use this recursive version
function getNestedItem(currentObject, listOfKeys) {
if (listOfKeys.length === 0 || !currentObject) {
return currentObject;
}
return getNestedItem(currentObject[listOfKeys[0]], listOfKeys.slice(1));
}
console.log(getNestedItem(inputMapping, "sections.general".split(".")));
You don't need to use eval() here. You can just use [] to get values from an object. Use a temp object to hold the current value, then update it each time you need the next key.
function getNode(mapping, name) {
var n = name.split(".");
if (n.length === 1) {
return mapping[name];
} else {
var tmp = mapping;
for (var i = 0; i < n.length; i++) {
tmp = tmp[n[i]];
}
return tmp;
}
}
I need to keep a stack of 10 items (value primitives, not objects) where no item is repeated. Here's my initial stab at an implementation. Any suggestions for improvements?
var items = [];
function newItem() {
return Math.floor(Math.random() * 50);
}
function inArray(arr, val) {
var in_arr, i;
in_arr = false;
i = arr.length;
if (i < 1) {
return in_arr;
}
do {
if (arr[i - 1] === val) {
in_arr = true;
break;
}
} while (--i);
return in_arr;
}
function addItem() {
var new_item;
while (items.length > 9) {
items.shift();
}
do {
new_item = newItem();
} while (inArray(items, new_item));
items.push(new_item);
}
while (items.length > 9) {
items.shift();
}
can be written without iteration as
var len = items.length;
if (len > 9) {
items = items.slice(len - 9);
}
Since JS 1.6, inArray can be written as array.indexOf(element) != -1. Otherwise,
if (i < 1) {
return in_arr;
}
do {
if (arr[i - 1] === val) {
in_arr = true;
break;
}
} while (--i);
return in_arr;
can be written more simply as
while (i--) {
if (arr[i] === val) {
return true;
}
}
return false;
function inArray(arr, val) {
return !!~arr.indexOf(val);
}
with this shim if needed
function addItem(item) {
if (inArray(items, item)) return false;
if (items.length > 9) items = items.slice(len - 9);
items.push(item);
return true;
}
I would rewrite the hold thing like this:
function stack10() {
var items = arguments || [];
this.addItem = function (item) {
var len = items.length;
if (!!~items.indexOf(item)) return;
if (len > 9) items = items.slice(len - 9);
items.push(item);
}
this.peek = function() {
if (items.length === 0) return null;
return items[items.length-1];
}
this.pop = function () {
return items.pop();
}
}
var myStack = new stack10();
myStack.addItem(10);
myStack.peek(); // 10
myStack.pop(); // 10
myStack.pop(); // undefined
// default values
var myStack2 = new stack10(1,2,3,4);
myStack2.addItem(10);
myStack2.peek(); // 10
myStack2.pop(); // 10
myStack2.pop(); // 4
Why not use a heap? You can do O(lg n) insert and removal instead of O(n), and it's still in-place.