Sorry if this is a stupid question. I am a newbie to programming...
I have 3 values from a text input. I want 2 of these values to be stored into separate arrays for later access. finally I want to display a sum of these 3 values in my document.
What am I doing wrong?
Here is my code:
<script>
function displayCurrentBalance() {
var initialBalance = parseFloat(document.getElementById("initialBalance").value);
var inAmounts=[0];
var outAmounts = [0];
inAmounts.push(document.getElementById("amountIn").value);
outAmounts.push(document.getElementById("amountOut").value);
var sumIn = (inAmounts.reduce(function(a, b) {
return a + b[1];
}, 0));
var sumOut = (outAmounts.reduce(function(c, d) {
return c + d[1];
}, 0));
var result = initialBalance + sumIn - sumOut;
document.write(result);
};
displayCurrentBalance();
</script>
document.write(result); will overwrite your document before you even have a chance to enter the values. Make it display a value in another input box, or alert(result).
You should probably attach displayCurrentBalance to an onclick handler of some button, like <button onclick="displayCurrentBalance()">Calculate</button>.
document.getElementById("amountIn").value and similar calls will give you a string. You should use parseFloat or parseInt to convert it to an integer or a float.
You are likely calling the function before the elements are available in the page. Otherwise the script should be below the elements in the page.
You main problem is how you are using reduce. The values returned from the inputs are strings, so convert them to numbers before trying to add them (otherwise you will be concatenating strings, not adding numbers). You should probably validate the values too.
Also, reduce is called with the values of the members of the array, not the array itself (which is the 4th parameter provided to the callback, not the second), so:
var sumIn = (inAmounts.reduce(function(a, b) {
return +a + +b;
}, 0));
Modify the other call to reduce similarly. I don't think you need to provide an initial value since you initialise the array as [0]. Alternatively, keep the initial value in the call and initialise the array as [] (i.e. an empty array).
Rather than using document.write to display the result, better to write it as the value of a read–only input element so you can update it with subsequent calls as the user modifies the values in the other inputs.
Related
I store a lot of values in localStorage for an app and needed a way of converting the "string" back into a number - IF it was a number. The thought being if you force HTML <input type="number"> on your form, then the data going into the form and extracted from the form IS a number, but once stored - its converted to a string. So to repopulate that field later, you must read the localStorage value and convert it back to a number before repopulating the input field - otherwise you start getting a lot of reptitive warnings and sometimes errors because NUMBERS are expected, but localStorage is retrieving strings.
My method: Assuming the value is inputted as a number, then only a number (digits only) will be stored - thus you can assume only numbers will come out (even if they are a string). Knowing only numbers will come back allows for this:
var allVariables = {} ;
var reg = new RegExp(/^\d+$/) ; // this accounts for digits only
for (var x=0; x<localStorage.length;x++) {
var keyValue = localStorage.getItem(localStorage.key(x)) ;
if (reg.text(keyValue)) {
keyValue = parseInt(keyValue) ;
}
allVariables[localStorage.key(x)] = keyValue ;
}
I even expanded on this to account for true/false booleans...can't use 0/1 easily without get confused with a number. Another method I have seen is underscoring the key name to identify the typeof for later conversion:
ie:
key1_str
key2_boo
key3_int
key4_obj
key5_flo
Then identify the "_xxx" to convert that value appropriately.
I am asking to see others approach to this problem or suggestions and recommendations on how to improve it. Mine is not perfect...though neither is localStorage...but still looking for improvement.s
suppose you have "keyName" : "12345".
Tricky solution is var newInt = +localStorage.getItem('keyName')
this extra + will convert the string to integer.
Instead of storing lots of single keys you might consider storing whole objects to less numbers of storage keys that you stringfiy to json and parse when retrieving. JSON methods will retain type
var obj= {
id:100,
anotherProp:'foo'
}
localStorage.setItem('myObj',JSON.stringify(obj));
var newObj = JSON.parse(localStorage.getItem('myObj'));
console.log(typeof newObj.id)//number
try to convert:
function getProbablyNumberFromLocalStorage(key) {
var val = localStorage.getItem(key);
return (isNan(+val) || val==null) ? val : +val;
}
so the problem is simple . here i want to return the new nth element of an array according to the
previous nth element sent by the user.for example
['1','3','5','7','9','11']
if a user sends a value of 3 then I would like to return 7, if the user sends 5 then I would like to return 9 , if they send 7 then 11 and when they send 11 then I want to return 3. basically its like puting the array in a circular mode and return the next element.
here is my code.
var indices=['1','3','5','7','9','11'];
var index_to_add=2;
var uservalue='1';/// will be sent by the user
var index=indices.indexOf(uservalue);
return indices[index+index_to_add];
everything here works fine but when the array finishes or nears the end then I get undefined instead of element from the first. how can i get the element from the beginning if the element index is undefined or the array finishes?
Using the Modulo operator:
return indices[(index+index_to_add) % indices.length];
Note: this will only handle the case when uservalue is actually part of the array. You might want to add a clause like if(index === -1) return 'Uservalue not in array.' or throw an error.
If I've interpreted your question correctly, a solution would be to encapsulate the processing within a recursive function, if you're after readable code and are unfamiliar with the Modulo function (doing it this way also makes it easier to change the process in the future):
const indices=['1','3','5','7','9','11'];
var index_to_add=2;
var uservalue='1';/// will be sent by the user
console.log(GetElemAtIndex(GetIndex(userValue) + index_to_add));
function GetIndex(userValue) {
return indices.indexOf(userValue); // If this is -1 the user has entered something not in the array
}
function GetElemAtIndex(toFind) {
if (indices.length > toFind) {
return indices[toFind];
}
else {
return GetElemAtIndex(toFind - indices.toLength);
}
}
The modulo function in Taxel's answer is a more efficient way of doing the GetElemAtIndex block.
This is an extremely beginner question, but i have a value that i want to transform multiple times, each time taking the output from the previous result as input.
Lets say i want to iterate through an array of characters [a,6,b,4] and append each of them the word brownbear. The final output that i would want is brownbeara6b4. Also, I'm not looking for a solution that just dumps the context of the array and concatenates it to the word. I need something that can iteratively transform data, no matter what the use case is.
To maybe provide another example, i want to run a function x amount of times on some value. Each time I want to take the output of the function and use it as input for the next time the function is ran.
How would i solve this using JS?
Maybe you are looking for a recursive function that runs X times. In that case, this can be helpful.
Basically what I'm doing here is to call the same function with the transformed data of each iteration over and over until i reach X amount of times.
var my_array = ["a", "1", "b", "2"]
var times = 2
function iterative_function(data, times_to_be_run = 1){
if(times_to_be_run > 0){
var transformed_data = data.map(a=> a + " hello")
return iterative_function(transformed_data, times_to_be_run - 1)
}else{
return data
}
}
console.log(
iterative_function(my_array, times)
)
I have a form a where fields are named like data[Field][0][value], data[Field][1][value], et cetera, where the integer increments but the rest stays the same. Is there a way of finding out the lowest available integer value with jQuery?
My form uses JS to dynamically add and remove fields (some of which are created by the PHP backend on page load), so I need the lowest integer so as to create fields without conflicts.
Right now on page load, I set field_count to $( "input[name$='[value]'" ).length; and then increment it as I create my inputs. This prevents any namespace collisions, however it doesn't take removed inputs into consideration: I'd like to be able to re-use the names of removed fields.
If you can address data[Field][0] ... data[Field][n], then I would say data[Field] is an Array and data[Field].length returns the current length of that Array. In that case the last value would then be in data[Field][data[Field].length-1] and the next available integer (index) would be data[Field].length.
Just for fun and to demonstrate an alternative: if you ditch the 'naming scheme' and use a data-attribute to keep track of the input fields, something like <input type="text" data-idx="1"> you could use a method to dynamically determine the lowest slot available:
function getFreeSlot(inputFields) {
var freeslots = []
,idxs = inputFields.map(
function (i, el) { return +$(el).attr('data-idx');}
).toArray()
idxs.every( function (v,i) {
void( v-(i ? 1 : 0) !== this[(i>0 ? i-1 : 0)]
&& freeslots.push(this[(i>0 ? i-1 : 0)]+1) );
return v; }, idxs );
return freeslots.length ? freeslots[0] : idxs.length+1;
}
Working example
Assuming your description is of the name attribute of the dynamically created/destroyed fields on the page (in other words, <input name="Data[Field][0][value]">):
var $lastField = $('[name^=Data\\[Field\\]\\[][name$=\\]\\[value\\]]').last();
var lastField = $lastField[0];
This should get the last element in the DOM with a name matching the regex Data[Field][.*][value]. If you want to ensure that the middle bit is a number, you need to get a little more involved:
var $lastField = $('[name^=Data\\[Field\\]\\[').filter(function(idx, element) {
return /Data\[Field\]\[[0-9]+?\]\[value\]/.test($(this).attr('name'));
}).last();
var lastField = $lastField[0];
Can you keep a list of the removed elements and then just pop one of those of the list to use when you need to create a new one (and if the list is empty, just increment your field_count as you are doing now).
I have an dynamic array and I want to exclude the first part of the string, but I don't know how many objects there will be after the first part and I want to include them all in a new string.
string = "text.'''hi''','''who''' '''are''' '''you'''. I'm ken and you're barbie"
x = string.split("'''")[1]
Is there something I can do to include them all? like [1..?]
I have JQuery but don't think that would be necessary right?
shift:
Removes the first element from an array and returns that element. This method changes the length of the array.
Code:
x = theString.split("'''");
var firstElement = x.shift();
// Now x is the shifted array.
x[0];
You seem to want:
x = string.split("'''").slice(1);
This will return all elements of the array starting at index 1.