I work on distance calculation between coordinates and I built something which works fine.
var pointsCoordinates = [[5,7],[5,8],[2,8],[2,10]];
function lineDistance(points) {
var globalDistance = 0;
for(var i=0; i<points.length-1; i++) {
globalDistance += Math.sqrt(Math.pow( points[i+1][0]-points[i][0] , 2 ) + Math.pow( points[i+1][1]-points[i][1] , 2 ));
}
return globalDistance;
}
console.log(lineDistance(pointsCoordinates));
I would like to improve it a little bit and send a prompt to store coordinates sent by users.
example:
alert(prompt("send me random coordinates in this format [,] and I will calculate the distance))
I would like to store theses coordinates and calculate the distance with my function which works.
I know I have to use push but it doesn't works, someone can help me to write it? I know it's simple but... I can't do it.
Thank you very much
Working and tested code. Take coordinates from the prompt and pass it to the lineDistance function and convert passed string into array.
function lineDistance(points) {
var globalDistance = 0;
var points = JSON.parse(points); // convert entered string to array
for(var i=0; i<points.length-1; i++) {
globalDistance += Math.sqrt(Math.pow( points[i+1][0]-points[i][0] , 2 ) + Math.pow( points[i+1][1]-points[i][1] , 2 ));
}
return globalDistance;
}
var pointsCoordinates = prompt("send me random coordinates in this format [,] and I will calculate the distance");
if (coordinates != null)
console.log(lineDistance(coordinates)); //[[5,7],[5,8],[2,8],[2,10]]
else
alert("Entered value is null");
Hope this will help you.
var userPrompt = prompt("send me random coordinates");// e.g [100,2] [3,45] [51,6]
var pointsCoordinates = parseCoordinates(userPrompt);
function parseCoordinates(unparsedCoord) {
var arr = unparsedCoord.split(" ");
var pair;
for (var i = 0; i < arr.length; i++) {
pair = arr[i];
arr[i] = pair.substr(1, pair.length - 2).split(",")
}
return arr;
}
function lineDistance(points) {
var globalDistance = 0;
for(var i = 0; i < points.length - 1; i++) {
globalDistance += Math.sqrt(Math.pow(points[i + 1][0] - points[i][0], 2) + Math.pow(points[i+1][1]-points[i][1], 2));
}
return globalDistance;
}
console.log(pointsCoordinates);
console.log(lineDistance(pointsCoordinates));
If you use prompt you don't need to also wrap it with alert.
Also, prompt will return with a string value, so you'll need to parse the data you're getting back (unless you're fine with a string)
In this case, since you want to get back an array of points, parsing can be a more complicated than just converting values. My recommendation is to use JSON.parse() to parse the input array
In your case you could use this code
var coordString = prompt("send me random coordinates in this format [,] and I will calculate the distance");
try {
var coordinates = JSON.parse(coordString);
// now check that coordinates are an array
if ( coordinates.constructor === Array ) {
// this might still fail if the input array isn't made of numbers
// in case of error it will still be caught by catch
console.log(lineDistance(coordinates));
}
} catch(error) {
// if something goes wrong you get here
alert('An error occurred: ' + error);
}
I recommend reading the MDN docs for prompt() if you want to know what else you can do with them.
Also, the docs for JSON.parse() can be useful if you want to parse values from a text string.
Related
Currently working on an application which requires to display a set of values in different currencies. This is part of an application but everything I provide here should be enough as this is the main section I am working with. I have a json file which is read in and it is stored into an array called valuesArray, this array has all the information, such as the amount, currency, etc. With the currencies being sorted with highest first to the lowest on display like this:
EUR 500.00
USD 200.00
This is the code that I have created but it seems like this wouldn't be effective the more currencies I have. I've just put an array declaration above the function but just above this function is where I do all the json stuff and adding it into the array. $scope.valuesArray has data at this point.
$scope.valuesArray =[];
$scope.total = function()
{
var eur_total = 0;
var usd_total = 0;
if (typeof $scope.valuesArray != 'undefined')
{
var length = $scope.valuesArray.length;
for (var i = 0; i<length ; i++)
{
switch($scope.valuesArray[i].currency)
{
case "USD":
usd_total += parseFloat($scope.valuesArray[i].value);
break;
default:
eur_total += parseFloat($scope.valuesArray[i].value);
break;
}
}
}
var cost_total= [usd_total,eur_total];
total.sort(function(a, b){return b-a});
return format_to_decimal(total[0]) + "\x0A" + format_to_decimal(total[1]);
}
In my for loop I go through every single data in the array and break each currency down within the switch statement and finding the total amount of each currencies.
The last bit is kind of temporary as I couldn't figure out a different way of how to do it. I sort the totals for the currencies I have from the highest at the top.
I return the function with a function call for format_numeric_with_commas which gives me the value in proper currency format and this displays the value. Will update this and add that code when I get to it. But I have used the indexes as a rough logic to show what I want to get out of it. So in this case, total[0] should be 500.00 and total[1] should be 200.00.
On top of this I want to be able to display the currency type for each. So like the example above.
You can try to save all the calculations in the array with currency index.
$scope.valuesArray = [];
$scope.total = function () {
var totalsArray = [];
if (typeof $scope.valuesArray != 'undefined') {
var length = $scope.valuesArray.length
for (var i = 0; i < length; i++) {
if (!totalsArray[$scope.valuesArray[i].currency]) {
totalsArray[$scope.valuesArray[i].currency] = 0;
}
totalsArray[$scope.valuesArray[i].currency] += $scope.valuesArray[i].value;
}
}
var cost_total = [];
for (var k in totalsArray) {
cost_total.push(currency:k,value:totalsArray[k]);
}
cost_total.sort(function (a, b) {
return b.value - a.value
});
return format_to_decimal(cost_total[0].value)+cost_total[0].currency + "\x0A" + format_to_decimal(cost_total[1].value);
I have an algorithm where the user will enter a string and I will parse it into an array of 2+ dimensions. So, for example, the user can enter 1,2,3;4,5,6 and set the text to be parsed by the semicolon and the comma. The first pass through will create an array with 2 entries. The second pass through will create a 3 entry array in both prior spots.
The user can add or remove the number of text items to be used to parse the original string such as the semicolon or comma, meaning the resulting array can have as many dimensions as parsing items.
This doesn't seem like a difficult problem, but I have run into some snags.
Here is my code so far.
vm.parsers = [';', ','];
vm.inputString = "1,2,3,4,5;6,7,8,9,10";
function parseDatasetText( )
{
vm.real = vm.parseMe( vm.inputString, 0);
};
function parseMe( itemToParse, indexToParse )
{
if ( indexToParse < vm.parsers.length )
{
console.log('Parsing *'+itemToParse+'* with '+vm.parsers[indexToParse]);
var tempResults = itemToParse.split( vm.parsers[indexToParse] );
for (var a=0; a<tempResults.length; a++)
{
console.log('Pushing '+tempResults[a]);
tempResults[a] = vm.parseMe( tempResults[a], parseInt( indexToParse ) + 1 )
console.log('This value is '+tempResults[a]);
}
}else
{
console.log('Returning '+itemToParse);
return itemToParse
}
};
As you can see from the console logs, the algorithm spits out an undefined after the last parse, and the final answer is undefined.
Maybe I just haven't slept enough, but I was thinking that the array would recursively populate via the splits?
Thanks
function parseDatasetText(){
//composing parser from right to left into a single function
//that applies them from left to right on the data
var fn = vm.parsers.reduceRight(
(nextFn, delimiter) => v => String(v).split(delimiter).map(nextFn),
v => v
);
return fn( vm.inputString );
}
Don't know what else to add.
You can use a simple recursive function like the following (here an example with 3 different delimiters):
function multiSplit(xs, delimiters) {
if (!delimiters.length) return xs;
return xs.split(delimiters[0]).map(x => multiSplit(x, delimiters.slice(1)));
}
data = '1:10,2:20,3:30;4:40,5:50,6:60';
res = multiSplit(data, [';', ',', ':']);
console.log(res)
The following function should suit your requirements, please let me know if not
var parsers = [';', ',', ':'],
inputString = "1:a,2:b,3:c,4:d,5:e;6:f,7:g,8:h,9:i,10:j",
Result = [];
function Split(incoming) {
var temp = null;
for (var i = 0; i < parsers.length; i++)
if (incoming.indexOf(parsers[i]) >= 0) {
temp = incoming.split(parsers[i]);
break;
}
if (temp == null) return incoming;
var outgoing = [];
for (var i = 0; i < temp.length; i++)
outgoing[outgoing.length] = Split(temp[i])
return outgoing;
}
Result = Split(inputString);
try it on https://jsfiddle.net/cgy7nre1/
Edit 1 -
Added another inputString and another set of parsers: https://jsfiddle.net/cgy7nre1/1/
Did you mean this?
var inputString = "1,2,3,4,5;6,7,8,9,10";
var array=inputString.split(';');
for (var i=0;i<array.length;i++){
array[i]=array[i].split(',');
}
console.log(array);
I've just started learning coding on code academy and I'm really new to this.
I'm trying to make this program ask the user for values which it adds to an array from which it calculates the sample standard deviation.
// This array stores the values needed
var figures;
getStandardDeviation = function() {
// I need at least two figures for a standard deviation
figures[0] = prompt("Enter a number:");
figures[1] = prompt("Enter a number:");
// Checks whether user wishes to add more values to the array
var confirm = prompt("Would you like to add another? (Y or N)").toUpperCase();
// I can't figure out why the following if statement is not executed
// It checks whether the user wishes to add more values and adds them to the array
// If not it breaks the for loop
if (confirm === "Y"){
for ( i = 0; i === 100; i++){
figures[i + 2] = prompt("Enter a number:");
confirm = prompt("Would you like to add another figure? (Y or N)").toUpperCase();
if (confirm === "N"){
break;
}
}
}
// The rest of the code works fine from here onwards
var sumx = 0;
var n = figures.length;
for(var i = 0 ; i < n ; i++) {
sumx += figures[i];
}
console.log("Sum = " + sumx);
var sumXsq = 0;
for( i = 0 ; i < n ; i++) {
sumXsq += (figures[i] * figures[i]);
}
console.log("Sum x squared = " + sumXsq);
var sxx = (sumXsq - (sumx * sumx)/n);
console.log("Sxx = " + sxx);
var v = sxx/(n - 1);
console.log("Variance = " + v);
var standardDev = Math.sqrt(v);
console.log("Standard Deviation = " + standardDev);
};
getStandardDeviation();
The program is supposed to ask me if I want to add more values to the array, then when I confirm, it gives me a prompt to add more values.
Currently, when I execute the program I input the numbers 56 and 67. The code then asks me if I wish to add more values, I then confirm this. Instead of letting me add more values it ignores this and calculates the standard deviation with the first two values (56 and 67).
The output is:
Sum = 05667
Sum x squared = 7625
Sxx = -16049819.5
Variance = -16049819.5
Standard Deviation = NaN
for ( i = 0; i === 100; i++){[...]} means
Set i to 0
If it's not true that i === 100 (that is: if i is not 100), end the loop
Do whatever I put inside the {} braces, once
Do i++
Back to 2
As the initial value for i is 0 and not 100, the code inside the loop is never executed. If you want it to go from 0 to 99, it should be for ( i = 0; i < 100; i++).
You don't actually need a for loop, though. A while loop would be better. A loop like while (true){[...]} would run until it hit a break statement. As you wouldn't have the i in that case, you could use figures.push(parseFloat(prompt("Enter a number:"))) instead (you should use parseFloat, as per what Vincent Hogendoorn said) . push adds a new value at the end of an array, so it's exactly what you need. Something like:
if (confirm === "Y"){
while (true){
figures.push(parseFloat(prompt("Enter a number:")));
confirm = prompt("Would you like to add another figure? (Y or N)").toUpperCase();
if (confirm === "N"){
break;
}
}
}
You could also change it so it doesn't ask if you want to stop if you don't have at least two values. That way you would be able to leave out that first part:
figures[0] = prompt("Enter a number:");
figures[1] = prompt("Enter a number:");
indeed your figures variable isn't defined as an array, like #James Donnely says.
Keep in mind you also fill in strings, so if you want to add up values you have to convert them to values.
you can use something like parseFloat for this.
if you don't use it, you sum up strings. 3+4 will be 34 instead of 7.
Your figures variable isn't defined as an array. Because of this figure[1] = prompt(...) never gets hit and a TypeError is thrown on var n = figures.length;.
Change:
var figures;
To:
var figures = [];
JSFiddle demo.
You can then replace the for loop you're using after if (confirm === "Y") with a recursive function:
// Push a user input number into the figures array
figures.push(prompt("Enter a number:"));
// Function to add a new number and ask if we want to add more
function addNewNumber() {
// Push a new user input number into the figures array
figures.push(prompt("Enter a number:"));
// Ask if the user wants to add another number
if (confirm("Do you want to add another number?"))
// If they do, call this function again
addNewNumber();
}
// Trigger the function for the first time
addNewNumber();
JSFiddle demo with recursion.
function StandardDeviation(numbersArr) {
//--CALCULATE AVAREGE--
var total = 0;
for(var key in numbersArr)
total += numbersArr[key];
var meanVal = total / numbersArr.length;
//--CALCULATE AVAREGE--
//--CALCULATE STANDARD DEVIATION--
var SDprep = 0;
for(var key in numbersArr)
SDprep += Math.pow((parseFloat(numbersArr[key]) - meanVal),2);
var SDresult = Math.sqrt(SDprep/numbersArr.length);
//--CALCULATE STANDARD DEVIATION--
alert(SDresult);
}
var numbersArr = [10, 11, 12, 13, 14];
StandardDeviation(numbersArr);
I'm am working on a script to count the number of times a certain string (in this case, coordinates) occur in a string. I currently have the following:
if (game_data.mode == "incomings") {
var table = document.getElementById("incomings_table");
var rows = table.getElementsByTagName("tr");
var headers = rows[0].getElementsByTagName("th");
var allcoord = new Array(rows.length);
for (i = 1; i < rows.length - 1; i++) {
cells = rows[i].getElementsByTagName("td");
var contents = (cells[1].textContent);
contents = contents.split(/\(/);
contents = contents[contents.length - 1].split(/\)/)[0];
allcoord[i - 1] = contents
}}
So now I have my variable allcoords. If I alert this, it looks like this (depending on the number of coordinates there are on the page):
584|521,590|519,594|513,594|513,590|517,594|513,592|517,590|517,594|513,590|519,,
My goal is that, for each coordinate, it saves how many times that coordinate occurs on the page. I can't seem to figure out how to do so though, so any help would be much appreciated.
you can use regular expression like this
"124682895579215".match(/2/g).length;
It will give you the count of expression
So you can pick say first co-ordinate 584 while iterating then you can use the regular expression to check the count
and just additional information
You can use indexOf to check if string present
I would not handle this as strings. Like, the table, is an array of arrays and those strings you're looking for, are in fact coordinates. Soooo... I made a fiddle, but let's look at the code first.
// Let's have a type for the coordinates
function Coords(x, y) {
this.x = parseInt(x);
this.y = parseInt(y);
return this;
}
// So that we can extend the type as we need
Coords.prototype.CountMatches = function(arr){
// Counts how many times the given Coordinates occur in the given array
var count = 0;
for(var i = 0; i < arr.length; i++){
if (this.x === arr[i].x && this.y === arr[i].y) count++;
}
return count;
};
// Also, since we decided to handle coordinates
// let's have a method to convert a string to Coords.
String.prototype.ToCoords = function () {
var matches = this.match(/[(]{1}(\d+)[|]{1}(\d+)[)]{1}/);
var nums = [];
for (var i = 1; i < matches.length; i++) {
nums.push(matches[i]);
}
return new Coords(nums[0], nums[1]);
};
// Now that we have our types set, let's have an array to store all the coords
var allCoords = [];
// And some fake data for the 'table'
var rows = [
{ td: '04.shovel (633|455) C46' },
{ td: 'Fruits kata misdragingen (590|519)' },
{ td: 'monster magnet (665|506) C56' },
{ td: 'slayer (660|496) C46' },
{ td: 'Fruits kata misdragingen (590|517)' }
];
// Just like you did, we loop through the 'table'
for (var i = 0; i < rows.length; i++) {
var td = rows[i].td; //<-this would be your td text content
// Once we get the string from first td, we use String.prototype.ToCoords
// to convert it to type Coords
allCoords.push(td.ToCoords());
}
// Now we have all the data set up, so let's have one test coordinate
var testCoords = new Coords(660, 496);
// And we use the Coords.prototype.CountMatches on the allCoords array to get the count
var count = testCoords.CountMatches(allCoords);
// count = 1, since slayer is in there
Use the .indexOf() method and count every time it does not return -1, and on each increment pass the previous index value +1 as the new start parameter.
You can use the split method.
string.split('517,594').length-1 would return 2
(where string is '584|521,590|519,594|513,594|513,590|517,594|513,592|517,590|517,594|513,590|519')
I'm attempting to teach myself javascript. I chose something I assumed was simple, but ran into problems relatively quickly.
I'm attempting to search a string for another string given by the user.
My code so far is:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = [];
var one = 0;
var two = 0;
var k = 0;
var sourceSearch = function(text) {
for(i = 0; i < source.length; i++) { //for each character in the source
if(source[i] === searchString[0]) { //if a character in source matches the first element in the users input
one = source.indexOf(i); //confused from here on
for(p = searchString.length; p > 0; p--) {
}
}
}
};
sourceSearch(searchString);
My idea was:
check to see if the first loop finds a character that matches the first character in the user input
if it matches, check to see if the next X characters after the first match the next X characters in the source string
if they all match, push them to the hits array
My problem: I have no idea how to iterate along the arrays without nesting quite a few if statements, and even then, that wouldn't be sufficient, considering I want the program to work with any input.
Any ideas would be helpful. Thanks very much in advance.
Note: There are a few un-used variables from ideas I was testing, but I couldn't make them work.
You can try:
if (source.indexOf(searchString) !== -1) {
// Match!
}
else
{
//No Match!
}
As the other answers so far point out, JavaScript strings have an indexOf function that does what you want. If you want to see how it's done "by hand", you can modify your function like this:
var sourceSearch = function(text) {
var i, j, ok; // always declare your local variables. globals are evil!
// for each start position
for(i = 0; i < source.length; i++) {
ok = true;
// check for a match
for (j = searchString.length - 1; ok && j >= 0; --j) {
ok = source[i + j] === searchString[j];
}
if (ok) {
// searchString found starting at index i in source
}
}
};
This function will find all positions in source at which searchString was found. (Of course, you could break out of the loop on the first success.) The logic is to use the outer loop to advance to each candidate start position in source and use the inner loop to test whether that position actually is the position of a match to searchString.
This is not the best algorithm for searching strings. The built-in algorithm is much faster (both because it is a better algorithm and because it is native code).
to follow your approach, you can just play with 2 indexes:
var sourceSearch = function(text) {
j = 0;
for(i = 0; i < source.length; i++) {
if(source[i] === text[j]) {
j++;
} else {
j = 0;
}
if (j == text.length) {
console.log(i - j); //this prints the starting index of the matching substring
}
}
};
These answers are all pretty good, but I'd probably opt for something like this:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = source.split(searchString);
var hitsCount = hits.length - 1;
This way you have all of the data you need to figure out where each hit occurred in he source, if that's important to you.