I think this question should be an easy one. I use a regex expression which, actually is:
str_pow = str_input.match(/(?:x)[^][+-]?\d{1,4}\s/g);
The problem lays in that I need only numbers, though they're still of string type(don't think about this), but not this part x^. Currently the how str_pow looks like is this
This means two things: I've to either edit my regex mask, or to find a way to cut the first two "x^" characters of for each element i of the array. Can you help me to do this, because I tried to slice but it was an unsuccessful experiment.
You can loop the array:
var a = ["x^5 ", "x^4 ", "x^2 ", "x^1 "];
for(var i = 0; i< a.length; i++) {
a[i] = parseInt(a[i].substring(2, a[i].length).trim(), 10);
}
console.log(a);
Related
I was working on counting sort1 problem on hackerrank. I am using JavaScript to solve the problem.
Standard input is providing a number and an array which I was reading like this
var inp = input.split('\n')
var n = parseInt(inp[0]); //Number of elements
var ar = inp[1].split(' ').map(function(item){
return parseInt(item);
}); //Array of numbers.
I was using above code in almost all of my solutions, it always worked.
Then I process the above array ar in for loop which is giving runtime error in one of the test cases(last testcase).
for(var i = 0; i < n; i++) {
var number = ar[i];
//more code
}
But if I don't parse elements of the array using map function but parse them later in for loop, one by one, I don't get any error.
var ar = in[1].split(' '); //Array of numbers in string format
for(var i = 0; i < n; i++) {
var number = parseInt(ar[i]);
//more code
}
Can Anyone explain Why?
in is a keyword, and you are trying to use it as a variable. I'm not sure why it says "Runtime Error", since this is actually a parsing error. Once renamed to something else, I could run the first two paragraphs error-free.
The only problem I remember having on Hackerrank that the .split() method often gave an empty string ("") as the last element of the array. Probably that's why you failed on the last test case.
Make your logic like:
if(arr[i] !== "")
// perform operations
else
break;
Also, you can't use in as a identifier because it is a reserved keyword.
So Im looking for help for writing a simple function in javascript. What I am trying to do is create an array of 6 name and print only those ending in "ie" or "y".
Here is my code - any help is appreciated. It unfortunately never reaches the function :(
//An array of names
var nameList = new Array("Freddie", "Mary", "Thomas", "Suzie", "Terry", "Kevin");
//Prints names before searching
document.write(nameList);
function e_names(nameList) {
for (var index = 0; index < arrayList.length; index++) {
var name = arrayList[index];
if (name == /\bie\b/ || name == /\by\b/)
document.write("",name, " </ br>");
index++;
} //End of for loop
} //End if method
Use /(ie|y)$/ ($ is used to match the end) to test it:
if (/(ie|y)$/.test(name))
It unfortunately never reaches the function :(
In your code, you are defining a function but then never executing it. Execute it like so:
e_names(namesList);
The loop has a bug:
for (var index = 0; index < arrayList.length; index++) {
arrayList is not defined, at least not in this code. It could be a previously defined or global variable, but then why does the function take a parameter called nameList? I think this is a simple typo.
if (name == /\bie\b/ || name == /\by\b/)
I am not sure what it means to equal a regular expression, but I would hazard a guess it won't do what you want. I think you want the .test function such as:
if (/\bie\b/.test(name) || /\by\b/.test(name))
Your pattern includes \b, the word boundary both before and after the y or ie. Therefore, it will only match strings that have i or ie as exact strings or with spaces around them. They won't match array or key or cookie. I think you meant to anchor them to end of string as suggested by #xdazz's answer. He even OR'ed the two expressions together for you:
if (/(ie|y)$/.test(name))
Finally, you double-increment index:
index++;
This will only iterate over "Freddie", "Thomas", and "Terry" because you increment twice. The index++ at the end of the loop construct is sufficient. Take this line out.
Altogether now:
//An array of names
var nameList = [ "Freddie", "Mary", "Thomas", "Suzie", "Terry", "Kevin" ];
//Prints names before searching
document.write(nameList);
function e_names(names) {
for (var index = 0; index < names.length; index++) {
var name = arrayList[index];
if (/(ie|y)$/.test(name)) {
document.write("",name, " </ br>");
}
} //End of for loop
} //End if method
e_names(nameList);
Note that I renamed the parameter so that it doesn't cause confusion with scoping and I also put curly braces around your if block. I usually don't change other people's code style, but I felt it was needed in this case to make it clearer.
I also changed the array construction to use the literal notation. Much debate has been had around the new Array constructor. It's probably safe for this example, but if there is a single element or the array contents are dynamic, it gets confusing. For example, what does new Array(17) mean? It means create an array with 17 null references in it. It does not create an array with the number 17 in it. For that reason, my advice is to use the [ ] syntax. For details, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
I am trying to build a simple script to work with a Google Spreadsheet. The spreadsheet takes input from a Google Form, so there is a series of values in the spreadsheet like this:
My goal is to write a script that would strip the number from each form input in a user-specified range, then add all the numbers to provide a single score. So, for example, the user could type =sumColumns(H2:K2) in a cell, and it would return the sum of the scores (for the sample screenshot I posted, it would return the result of 3+3+0+3, 9).
Here is the code that I wrote to do this:
function sumColumns(values) {
var sum = 0;
for(var i = 0; i <= values.length; i++){
var input = values[0][i];
var x = input.toString();
var y = x.charAt(0);
var num = parseInt(y);
sum += num;
}
return sum;
}
The problem is that it only ever seems to add two values together. So, when I put =sumColumns(H2:K2) in a cell in the spreadsheet, it only returns 6. Also, on line 3, if I change it from i <= values.length to i < values.length it only adds one number, so that I get 3 as a result. My guess is that I am misunderstanding the way that the Google Spreadsheet values are passed to the function, but I have been completely unable to make it work. I'd really appreciate any help!
Oops - edited & saved the question, wrote an answer - and forgot to save it. I let Serge beat me to it! And, as usual, Serge's answer works well (with integer values). But you did ask about how things worked, so here you go.
When you give a Custom Function a range as a parameter, H2:K2 in this case, the function receives a two-dimensional array, equivalent to the return value of Range.getValues(). You can test this easily, by (temporarily) changing your function to return a JSON representation of the parameter:
function sumColumns(values) {
return JSON.stringify(values); // For debugging, just return string showing values
...
Here's what you'll see in the cell that contains =sumColumns(H2:K2):
[["3 (Rarely)","3 (Frequently)","0 (Never)","3 (Frequently)"]]
That's showing an Array enclosed by [ .. ], with another Array inside, also enclosed by square brackets, and that array has four elements. If we change the range to be H2:K3 instead, we get this (with whitespace added for clarity):
[
["3 (Rarely)","3 (Frequently)","0 (Never)","3 (Frequently)"],
["","","",""]
]
Now that you know that, it's easy to see why your function was giving the results it did.
First, for(var i = 0; i <= values.length; i++) is using the wrong array bounds to loop over, since values.length will tell us how many rows are in values. In H2:K2, that length is 1. Instead, we need to be looping over the columns in the first row (values[0]), with its 4 cells.
You were wondering about < vs <= for this loop - we do need to use < since it's a 0-based index, and .length returns a count of elements. So we end up with:
for (var i=0; i < values[0].length; i++){ ... }
Using parseInt() is a good choice, and works well for the values in your spreadsheet. It can be improved, though, by ensuring that any String values have leading non-numeric values stripped first - parseInt() can then find an Integer inside a string.
function sumColumns(values) {
return JSON.stringify(values); // For debugging, just return string showing values
var sum = 0;
for(var i = 0; i < values[0].length; i++){
var input = new String(values[0][i])
.replace( /^\D+/g, ''); // Strip any leading non-digits
sum += parseInt(input);
}
return sum;
}
I'm not good with custom function because I never use them but it seems that values is not really an array...
Comments in italic :
Hmmm embarrassing ... my first though was that it had to be a 2D array but I logged val[0] in my test and it returned an 'undefined' error... I must have mistyped something at that moment... Anyway, that's why I looked for a way around handling data as a string and using split and regex.
As usual with Mogsdad's answers you have an answer and all the explanations that go with it ;-) and, as often with him too, you get a better answer than mine.
(one restriction though (#Mogsdad) your comment about non integer values could be applied to your code as well... you simply strip out any decimal value with parseInt()...:-)
That said, your use case was well described and in the limits of this example both code should work as expected, Mogsdad's one being more 'academic' and programmatically correct.
end of comment.
Using this trick below it works as expected for any input range (1 or more row and columns):
function sumCol(val) { // returns the sum of all numeric values in range
var values = val.toString().split(',');
var sum = 0;
for(var n=0;n<values.length;++n){
sum+=Number(values[n].replace(/[^0-9+.]/ig,''));
}
return sum;
}
I changed also the number extraction mode to make it more universal.
So if you have a list of 50 words, and you want to see how deep into a word a reader must look to be able to count all of the unique words, how would you go about doing that?
I'm basically thinking about loading characters into an array, one-by-one, and then comparing them. There are so many characters and so many arrays to compare, though. I wonder what's the most efficient way, if there's already an efficient way out there?
I'm trying to use Javascript, right now.
var words = [sort(prompt("Please, insert the word list", "default value in the text field"););];
var encr_int: Number=0;
for (i=0, j=0, maxdif=0; j < word.length; i++) {
if(word[j].text.charAt(i) == word[j+1].text.charAt(i) AND i > maxdif) {
maxdif = i;
}
else if(word[j].text.charAt(i) != word[j+1].text.charAt(i) {
j+=1;
}
else if(word[j].text.charAt(i) == "") {
i = 0;
}
}
document.write(maxdif);
Above is my effort at writing the program based on the first answer.
A more efficient approach might be to store your set of words in a trie structure rather than a list. This is a hierarchical structure where each node contains the prefix characters of its children. This means that you don't have to compare against all words - once a certain prefix is found to match words without that prefix need are eliminated.
Although for 50 words speed is not likely to be an issue, the trie will enable you to minimise the number of character comparisons needed and you can keep track of the character count as you recurse down the hierarchy.
If absolute efficiency is a requirement then the precise way in which you organise the trie might become important for example it could be organised to be efficient taking account of the actual statistics of the searches being made against it.
Sort the list and then iterate through it, comparing each word with the subsequent word. Compare with a routine that tells you how many characters had to be checked before a difference was found. Keep track of the maximum "depth" as you go.
edit — a function to tell you the "similarity" of two words based on leading characters:
function similarity(w1, w2) {
var i, l = Math.min(w1.length, w2.length);
for (i = 0; i < l; ++i)
if (w1[i] !== w2[i]) break;
return i;
}
I have searched across the web though have not had any luck in correcting my issue. What I want to do is search an array for a substring and return the result. An example of the array is like this:
the_array = ["PP: com.package.id, NN: Package Name","PP: com.another.id, NN: Another Name"];
What I want to do is search the_array for com.package.id making sure that it appears between the "PP:" and ",". Also please note that the array will contain several thousand values. Hope you can help, thank you.
Easy way:
the_array.join("|").indexOf([str]) >= 0;
Other ways would be to loop thru the array using .each() or a simple for loop
Array.prototype.each = function(callback){
for (var i = 0; i < this.length; i++){
callback(this[i]);
}
}
the_array.each(function(elem){
console.log(elem.indexOf('<searchString goes here>'));
});