Pushing data into object clears the other values - javascript

I'm making trying to push data into an object, but as soon as I push data to userID.name, the value of userID.age gets reset(?) in the console. Here's my code:
if (input.indexOf("ben") >= 0){
var slot = splitInput.indexOf("ben");
console.log(slot)
i = slot + 1;
if (splitInput[i].indexOf(0) >= 0 || splitInput[i].indexOf(1) >= 0 || splitInput[i].indexOf(3) >= 0 || splitInput[i].indexOf(4) >= 0 || splitInput[i].indexOf(4) >= 0 || splitInput[i].indexOf(5) >= 0 || splitInput[i].indexOf(6) >= 0 || splitInput[i].indexOf(7) >= 0 || splitInput[i].indexOf(8) >= 0 || splitInput[i].indexOf(9) >= 0){
i = 0;
var slot = splitInput.indexOf("ben");
// console.log(slot)
i = slot + 1;
userID.age = splitInput[i];
console.log(userID);
} if (splitInput[i].indexOf("a") >= 0 || splitInput[i].indexOf("e") >= 0 || splitInput[i].indexOf("i") >= 0 || splitInput[i].indexOf("u") >= 0){
i = 0;
var slot = splitInput.indexOf("ben");
// console.log(slot)
i = slot + 1;
userID.name = splitInput[i];
console.log(userID);
}
}
Here's my splitInput:
var splitInput = input.split(" ");
input is gathered through a getElementById function.
When I manually log userID I get this error VM935:1 Uncaught ReferenceError: userID is not defined(…) which may have something to do with it, although console.log(userID) works fine.
If you need more information, please let me know.
Thanks in advance!

Before assigning to an object property, like UserID.age, you must first have defined UserID itself.
So put this before you access a property of UserID:
var userID = {};
Remarks on the code
The way you check for numbers and words with vowels is not really that nice. It has a lot of repetitive code. Also inside the if blocks you were searching again for the word "ben", while you had that already done... Seems unnecessary to do that again.
Have a look at this version of your code:
// Sample data
var input = 'ik ben 51 jaar';
var splitInput = input.split(" ");
// This was missing:
var userID = {};
// Move retrieval of slot before the `if` so it can be reused
var slot = splitInput.indexOf("ben");
if (slot >= 0){
console.log('slot:', slot);
i = slot + 1;
// Make sure you are not at the end of the array, and
// use a regular expression to see next word consists of digits only
if (i < splitInput.length && splitInput[i].match(/^\d+$/)){
// convert the word to number with unitary plus:
userID.age = +splitInput[i];
}
// You'll maybe want to do an else here.
// Use regular expression again; don't forget the "o"
else if (i < splitInput.length && splitInput[i].match(/a|e|i|o|u/)){
userID.name = splitInput[i];
}
console.log(userID);
}

Related

Why does my forloop run through my if statment only once?

I'm writing a calculator in JS and currently I'm writing the '=' function, now I pasted my code below, so I made exp = 5 + 5, everything works fine it tells me that total is 10, now when I do 5+5+5 it still says 10, it's as if the loop ins't working, because I want it to do 5+5 first, update the total to be 10 and then find the + operator again and then add whatever is after the plus, how do I do this? I have no idea why the loop isn't working
All help is appreciated,
Have a nice day,
larwa
function equal(){
var exp = document.form.textview.value;
var expArray = exp.split(/\b/);
console.log(expArray);
let total = 0;
for (let i = 0 ; i < expArray.length; i++){
console.log(expArray[0])
total = parseFloat(expArray[0])
if(i = '+' || '-' || '/' || '*'){
console.log(i);
n = expArray.indexOf(i)
total += parseFloat(expArray[n + 1]);
}
}
There are certain mistakes in your code.
The total should be initialized outside the for loop, otherwise it will generate incorrect total value.
if(i = '+' || '-' || '/' || '*'){, in this instead of using assignment operator i:e =, comparison operator i:e == or === (strict equality operator) should be used. As well separate comparison expressions are required i:e i=== '+' || i=== '-' || i=== '/' || i=== '*'. The i is nothing but index of the array elements, instead of i it should be array element. i:e expArray[i].
let exp = "5 + 5 + 5";
function equal() {
var expArray = exp.split(/\b/);
let total = parseFloat(expArray[0]);
for (let i = 0; i < expArray.length; i++) {
const dig = expArray[i].trim();
if (dig === '+' || dig === '-' || dig === '/' || dig === '*') {
total += parseFloat(expArray[i + 1]);
}
}
return total;
}
console.log(equal());
Try this
for (let i = 0 ; i < expArray.length; i++){
console.log(expArray[0])
total = parseFloat(expArray[0])
if(i == '+' || '-' || '/' || '*'){
console.log(i);
n = expArray.indexOf(i)
total += parseFloat(expArray[n + 1]);
}
The = operator is used for assigning values to a variable, however the == operator is used for comparison between two variables irrespective of the datatype of variable

How to delete an entry from my array in Javascript

This error kept troubling me for about 2 hours now... I'm making an idle game where you can have your own city and I'm making a building system right now, the problem is the game crashes whenever I delete from array (I have build queue which holds buildings to be built and then removes them) building from build queue. I tried .shift .pop .push .indexOf(0) === 0 and [0] === "" and .splice(1,1) it just comes up with like .splice is not a function or .pop is not a function for all of them.
Nothing worked. Please HELP!
if (buildValue === 100 && buildQueue.indexOf("house") === 0){
populationmax++;
// here i need a command that will remove first element from array called buildQueue.
buildValue = 0;
}
Removing From Array
if (buildValue === 100 && buildQueue.indexOf("house") === 0){
populationmax++;
buildQueue.splice(0, 1); //removes first element
buildValue = 0;
}
JS Snippet
x = [1, 2, 3];
alert(x); //1,2,3
x.splice(0, 1);
alert(x); //2,3
Adding To/Creating Array
First, you don't need to put a blank string inside the buildQueue array, this might actually cause problems later, just do this:
buildQueue = [];
Second, you are trying to add strings to your array as if it were a string, using +=. Doing this however, is turning your array into a string, which is why you're getting the warning about `.splice()' you need to add strings to your array like this:
buildQueue.push(someString);
This way buildQueue will remain an array of strings.
var buildValue = 0,
buildQueue = [""],
buildSpeed = 1/200;
if (buildQueue[0]){
buildValue += buildSpeed;
}
if (buildValue >= 100){
buildValue = 100;
}
if (buildValue === 100 && buildQueue.indexOf("house") === 0){
populationmax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("big house") === 0){
populationmax+=4;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("gold storage") === 0){
goldmax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("food storage") === 0){
foodmax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("wood storage") === 0){
woodmax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("stone storage") === 0){
stonemax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("iron storage") === 0){
ironmax++;
buildValue = 0;
}
buildSpeed = 0.2;
That is all i have to do with build. Also if you buy a building it will just add to array. eg gold storage will add buildQueue += "gold store"; And the spaces between lines inside ifs are supposed to have command that deletes the [0] element.

How to implement .map() using for()?

I have these array and variable:
var arr = [['one','blue'], ['two','red'], ['three','green']]
var variable = 'thre';
Also I have this code:
arr.map(function(x){
if(x[0].indexOf(variable) >= 0)
{
alert('Number is found');
}
});
As you know, map works as a loop, and in the array above, there is three items and then map executes its statement 3 times. So that alert will be run.
Now I'm trying to limit the mapping, I mean I want to execute a statement 2 times. So I user for() like this:
for ( var c = 0; c < 2; c++ ) {
if ( arr[c][0].indexOf(variable) >= 0 )
{
alert('number is found');
}
}
But ^ doesn't work, It gives me this error:
Uncaught TypeError: Cannot read property '0' of undefined {in line 2}
How can I fix it?
EDIT: Here is my code in reality:
ZippedArray.map(function(x){
if(x[0].indexOf(name) >= 0)
{
MatchesNames.push(x[0]);
MatchesIds.push(x[1]);
}
});
I want this output:
MatchesNames = MatchesNames.slice(0,2);
MatchesIds = MatchesIds.slice(0,2);
How to limit .map() ? I want something like break; after 2 times.
Based on your comments, it seems you want to loop until you've found two matches in the if condition.
In that case, you can use .some(), which will halt the loop as soon as you return true (or any truthy value).
ZippedArray.some(function(x){
if(x[0].indexOf(name) >= 0)
{
MatchesNames.push(x[0]);
MatchesIds.push(x[1]);
}
return MatchesNames.length == 2; // Breaks when this returns `true`
});
This example assumes that MatchesNames was empty before you called .some().
If there could be other items in the array, and you just want to push two more in at the most, then you could keep a count.
var found = 0;
ZippedArray.some(function(x){
if(x[0].indexOf(name) >= 0)
{
MatchesNames.push(x[0]);
MatchesIds.push(x[1]);
found++;
}
return found == 2;
});
If you want to use a traditional for loop, then do this:
var found = 0;
for (var i = 0; i < ZippedArray.length; i++) {
var x = ZippedArray[i];
if(x[0].indexOf(name) >= 0)
{
MatchesNames.push(x[0]);
MatchesIds.push(x[1]);
found++;
}
if (found == 2) {
break;
}
}
The code you posted does not throw an error.
But when you're limiting the loop count of iterating an array, you should add a range check for the index:
for (var c = 0; c < 2 && c < arr.length; c++) {
// or alternatively
for (var c = 0, l = Math.min(2, arr.length); c < l; c++) {

javascript value coming up empty not sure how to handle it

function updategeneral() {
//tmp = "fine_" + tmp + "_";
var actual = doc.findItem("1speed").value;
var posted = doc.findItem("2speed").value;
amt = "";
if (1speed != "" && 2speed != "") {
var a = 1 * 1speed;
var b = 1 * 2speed;
if (a - b <= 9) {
alert(amt);
amt = doc.getDefault("general_spb_1_to_15");
} else if (a - b <= 15) {
amt = doc.getDefault("general_spb_16_to_25");
} else if (a - b <= 25) {
amt = doc.getDefault("general_spb_15_to_19");
} else if (a - b <= 29) {
amt = doc.getDefault("general_spb_26+");
}
doc.findItem("mcare_amount").value = amt;
alert(doc.findItem("mcare_amount").value = amt);
}
}
Default values are:
general_spb_1_to_15=30.00 || general_spb_16_to_25=40.00 || general_spb_26+=50.00
My problem is when amt is empty or 0 it is always going to general_spb_1_to_15=30.00. I am not sure how to fix this- can someone please help? The values that I am using are 1speed = 20 and 2speed = 25 which is negative or empty.
Assuming your browser engine is interpreting 1speed and 2speed as variables (some will, some won't -- variable names aren't supposed to start with numbers so it would probably be wise to replace these with speed1 and speed2)...
But assuming that, then the case that you describe is seeing a value of a - b = -5 when processing your if statements, which means that it is being caught by
if (a - b <= 9) {
alert(amt);
amt = doc.getDefault("general_spb_1_to_15");
}
To change the result you are getting, you should add another option to the if statement structure. Perhaps:
if (b > a)
{
//do something for this special case
} else if (a - b <= 9) {
alert(amt);
amt = doc.getDefault("general_spb_1_to_15");
} else if ...
You may also want to specifically handle the case where one or both of speed1/speed2 are empty as an else on the outer if block.

Determine Document Order from Nodes

If I have two nodes in an HTML document, how can I tell which one comes first in HTML document order in Javascript using DOM methods?
For example,
function funstuff(a, b) {
//a and b can be any node in the DOM (text, element, etc)
if(b comes before a in document order) {
var t = b; b = a; a = t;
}
// process the nodes between a and b. I can handle this part
// when I know that a comes before b.
}
Resig to the rescue:
// Compare Position - MIT Licensed, John Resig
function comparePosition(a, b){
return a.compareDocumentPosition ?
a.compareDocumentPosition(b) :
a.contains ?
(a != b && a.contains(b) && 16) +
(a != b && b.contains(a) && 8) +
(a.sourceIndex >= 0 && b.sourceIndex >= 0 ?
(a.sourceIndex < b.sourceIndex && 4) +
(a.sourceIndex > b.sourceIndex && 2) :
1) +
0 :
0;
}
You can use the DOM function compareDocumentPosition which will return different numbers based on the two nodes' relationships:
DOCUMENT_POSITION_DISCONNECTED = 0x01;
DOCUMENT_POSITION_PRECEDING = 0x02;
DOCUMENT_POSITION_FOLLOWING = 0x04;
DOCUMENT_POSITION_CONTAINS = 0x08;
DOCUMENT_POSITION_CONTAINED_BY = 0x10;
Potentially the result could be the sum of more than one of these codes as the answer is a bitmask, but I can't imagine a situation where two of these conditions would be true at the same time. Also note that the "disconnected" result would be returned for instance with nodes that have been created but not added to the document tree yet
Rather difficult, I personally would itterate up each tree till I found a common ansester, then check which parent node(or the actual node if that low) comes first starting with firstChild and working through siblings, something like:
function OrderCheck(node1, node2){
var ar1 = [null, node1];
var ar2 = [null, node2];
for(var i = 1; ar1[i] != null; i++)
ar1[i+1]=ar1[i].parentNode;
for(var i = 1; ar2[i] != null; i++)
ar2[i+1]=ar2[i].parentNode;
ar1.reverse(); ar2.reverse(); // easier to work with.
i = 0;
while( ar1[i] === ar2[i] ){
if(ar1[i] === null)
return 0;
else
i++
}
if(ar1[i] === null)
return 2;
if(ar2[i] === null)
return 1;
if(i != 0){
var n = ar1[i-1].firstChild;
do{
if(n === ar1[i])
return 1;
if(n === ar2[i])
return 2;
}while(n = n.nextSibling);
}
return -1;// Shouldn't happen.
}
var order = OrderCheck(document.body, document.body.previousSibling);
if( order == 1){
// element 1 first
}else if(order == 2){
// element 2 first
}else{
// there was an error.
}
I did just edit this code in an attempt to fix two possible problems, I haven't tested this new edit however, so if something breaks I shall have to try again. (Edited again to fix a "doesn't even run" style bug).

Categories

Resources