How can I count these words, using script in google sheets? - javascript

I'd like to count an occurrence number of one word in a string, but Google Sheets is giving me an error, that it can't deal with the expression:
finalScores.push(preOutputTxt.match(nameArr[x])).length);
because there is null somewhere. How can I fix this?
Full code:
/**
*
*
*
* #customFunction
*/
function scoreCounting(scores, names){
//---variables---//
var scoresArr = [];
var preOutputTxt = "";
var finalScores = [];
var nameArr = [];
//---------------//
//---creating an array from names and scores (scores are in string type)---//
for(var w = 0; w < scores.length; w ++){
scoresArr.push(scores[w]);
}
for(var z = 0; z < names.length; z++){
nameArr.push(names[z]);
}
//---------------------------------------//
//---make one big string with names---//
for(var y = 0; y < scoresArr.length; y++){
preOutputTxt += scoresArr[y];
}
//----------------------------------------------//
//---counting how many times score (a name) occur, basing on name given by nameArr[]---//
for(var x = 0; x < nameArr.length; x++){
finalScores.push(preOutputTxt.match(nameArr[x])).length);
}
return finalScores;
}

As Tedinoz mentioned, it would be easier to offer specific help if you could share a spreadsheet.
But in the meantime, here are two snippets help explain how to get the count of a word in a longer string.
Example 1: If you use match() with the name as the input, you will get just the first match.
[This is because the method expects a regular expression. And passing a string (or a variable set to a string) is similar to a regex with no modifier.]
function example1() {
var preOutputTxt = 'abcabcabc';
var name = 'abc';
var output = preOutputTxt.match(name);
Logger.log('Output is %s. Length is %s.', output, output.length);
}
// Output is [abc]. Length is 1.0.
Example 2: But if you use a regular expression with a global modifier, you will get all the matches.
function example2() {
var preOutputTxt = 'abcabcabc';
var name = 'abc';
var re = new RegExp(name, 'g');
Logger.log('Regular expression is %s', re);
var output = preOutputTxt.match(re);
Logger.log('Output is %s. Length is %s.', output, output.length);
}
// Regular expression is /abc/g
// Output is [abc, abc, abc]. Length is 3.0.

Related

How to make element in Array change its' place

I'm beginner in JS. I've tried to understand Caesar Cipher ROT13, but it was too complicated for me. So I've tried to write my own code. Here it is below:
function encrip() {
var alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var str = "Ni Hao";
var string = str.toUpperCase();
for (var i = 0; i < string.length; i++) {
for (var k = 0; k < alphabet.length; k++) {
if(string.charAt(i) == alphabet[k]) {
/* console.log(string.charAt(i) + ' ' + alphabet.indexOf(alphabet[k])); */
}
}
}
}
encrip();
But I am stuck. How to do:
1. Get value from var str and then access to var alphabet , after change each letter from var str value to next 3 from alphabet (var str each element's current position would be changed) For example: Input: Ni Hao ==> output: QL KDR
2. Create universal code, I mean, not only for changing position by 3, but when I give value '5', each element would be changed by next 5 positions from alphabet. So output can be changed when I change its' value
I hope I explained everything clearly. Thanks everyone in advance for help!!
you can use the following function to encrypt english words, the 1st parameter is the string to encrypt and the 2nd for shifting
function encryp(str,pos){
var alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var strUC=str.toUpperCase();
var enc="";
for(var i=0;i<strUC.length;i++){
if(strUC.charAt(i)!=" "){
enc+=alpha.charAt((alpha.indexOf(strUC.charAt(i))+pos)%26)
}
else{
enc+=" "
}
// in your case pos=3
}
return enc;
}
console.log(encryp("NiHao",3));
You don't need two for loops to do this. Iterate over the input string and find the index of each character in the alphabet array, if found add the shift to it to get the encrypted character.
To handle overflow use the modulus operator to cycle through the array.
Also I assume that you are not going use any special symbols to do the encryption.
function encrip(string, shift) {
var alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
string = string.toUpperCase();
let arr = [];
for (var i = 0; i < string.length; i++) {
let char = alphabet.indexOf(string[i]) !== -1 ? alphabet[(alphabet.indexOf(string[i]) %26) + shift] : " ";
arr.push(char);
}
let encryp = arr.join("");
console.log(encryp);
return encryp;
}
encrip("Ni Hao", 3);
First of all, instead of your inner for loop scanning the whole alphabet array, you can use the built-in function indexOf:
alphabet.indexOf('K') // returns 10
Secondly, you'll want to build up your enciphered string in a separate variable. For each letter, get the index of that letter in the alphabet, add your cipher offset parameter to that index and add the resulting letter from the alphabet to your new string. An important step is that when you add to the index of the letter, you want to make sure the resulting index is within range for the alphabet array. You can do that using the % (modulo) operator, which will wrap high values back round to the start of the array. In full:
function encipher(input, offset) {
var alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var str = input.toUpperCase();
var result = '';
for (var i = 0; i < str.length; i++) {
letterIndex = alphabet.indexOf(str.charAt(i));
if (letterIndex === -1) {
result += str[i]; // if the letter isn't found in the alphabet, add it to the result unchanged
continue;
}
cipheredIndex = (letterIndex + offset) % alphabet.length; // wrap index to length of alphabet
result += alphabet[cipheredIndex];
}
console.log(result);
}
encipher('Ni Hao', 5); // output: 'SN MFT'

Printing in Javascript

i have a question that seems basic but i can't seem to figure it out.
Write a program that takes the value of a variable called “input” (declared as any whole number at the top of your program) and outputs a square made of asterisks () as large as the number (input). For example, if the “input” is declared with the value 5, your program would display a square made of 25 asterisks() – ie ; 5 asterisks () high, by 5 asterisks () long.
The code i've come up with so far is below. I don't really understand how to make a string continuously print. If i did star = i then it turns into numbers and will print the numbers. So how do i make it so they connect? I also can't figure out where i should put the new line. console.log(star "\n"); gives me an error. Please help :)
var input = 2;
var star = "*";
var i = 0;
do {
console.log(star);
i++;
} while (i < input);
You can use String.repeat() (ES6 only) along with \r\n to add new line
var input = 5,
star = "*",
str = [],
i = 0;
do {
str.push( Array(input).join(star) ); // use array(length).join
i++;
} while (i < input);
str = str.join("\r\n"); // add breaklines
console.log(str);
console.log Will output a single line to the console containing whatever you pass it as an argument. You are trying to print a line of n asterisks n times.
The first step you should take is constructing the string of asterisks. You can concatenate a string to another with the + operator:
var input = 2;
var star = "*";
var line = "";
for(var i = 0; i < input; i++) {
line = line + star;
}
Once you have constructed line you can then print it n times:
for(var i = 0; i < input; i++) {
console.log(line);
}
Hint: You could create an empty array and then create a loop ending at your wanted number of asterisks after which you will join all the members of the array together. (Writing the code here wouldn't help you much since you mentioned it's an homework).
You could approach this in two ways. If we call your input value n, then we can log either n strings each consisting of n stars, or we can log a single string, containing (n * n) stars, with line breaks after every nth star.
Below is an example of a function that could do this task.
function stars (input) {
var output = ''
for (var i = 0; i < input; i++) {
for (var j = 0; j < input; j++) {
output += '*'
}
output += '\n'
}
return output
}
You can use the repeat-function to print a character multiple times.
var input = 2;
var star = "*";
var i = 0;
while(i++ < input){
console.log(star.repeat(input));
}
This repeats the * character input times in input lines.

javascript string algorithm

Let's say I have a string variable called myString, and another string variable called myChar.
var myString = "batuhan"; // it's user input.
var myChar = "0"; // will be one character, always
What I need is, a function that returns all the combinations of myString and myChar.
Like:
"batuhan","batuha0n","batuh0an","batuh0a0n","batu0han","batu0ha0n","batu0h0an","batu0h0a0n","bat0uhan","bat0uha0n","bat0uh0an","bat0uh0a0n","bat0u0han","bat0u0ha0n","bat0u0h0an","bat0u0h0a0n","ba0tuhan","ba0tuha0n","ba0tuh0an","ba0tuh0a0n","ba0tu0han","ba0tu0ha0n","ba0tu0h0an","ba0tu0h0a0n","ba0t0uhan","ba0t0uha0n","ba0t0uh0an","ba0t0uh0a0n","ba0t0u0han","ba0t0u0ha0n","ba0t0u0h0an","ba0t0u0h0a0n","b0atuhan","b0atuha0n","b0atuh0an","b0atuh0a0n","b0atu0han","b0atu0ha0n","b0atu0h0an","b0atu0h0a0n","b0at0uhan","b0at0uha0n","b0at0uh0an","b0at0uh0a0n","b0at0u0han","b0at0u0ha0n","b0at0u0h0an","b0at0u0h0a0n","b0a0tuhan","b0a0tuha0n","b0a0tuh0an","b0a0tuh0a0n","b0a0tu0han","b0a0tu0ha0n","b0a0tu0h0an","b0a0tu0h0a0n","b0a0t0uhan","b0a0t0uha0n","b0a0t0uh0an","b0a0t0uh0a0n","b0a0t0u0han","b0a0t0u0ha0n","b0a0t0u0h0an","b0a0t0u0h0a0n"
Rules: myChar shouldn't follow myChar
How can I do that? Really my brain dead right now :/
It's possible to implement what you want using recursion.
// Example: allCombinations("abcd", "0") returns the array
// ["abcd", "abc0d", "ab0cd", "ab0c0d", "a0bcd", "a0bc0d", "a0b0cd", "a0b0c0d"]
function allCombinations(str, chr) {
if (str.length == 1)
return [str];
var arr = allCombinations(str.substring(1), chr);
var result = [];
var c = str.charAt(0);
for (var i = 0; i < arr.length; i++)
result.push(c + arr[i]);
for (var i = 0; i < arr.length; i++)
result.push(c + chr + arr[i]);
return result;
}
You may or may not have noticed this but this is basically counting in binary. If we define bit 0 to be the absence of myChar and bit 1 to be the presence of myChar, then the following sequence:
var myString = ".....";
var myChar = "1";
var sequence = [
".....1",
"....1.",
"....1.1",
"...1.."
];
is basically counting from 1 to 4 in binary:
var sequence = [
0b0000001,
0b0000010,
0b0000011,
0b0000100
];
Therefore, all you need is a for loop to count up to the bit amount of the length of the string plus 1 (because the position at the end of the string is also legal):
var len = Math.pow(2,myString.length+1);
for (var x = 0; x < len; x++) {
// x in binary is all the possible combinations
// now use the "1" bits in x to modify the string:
// Convert myString to array for easy processing:
var arr = myString.split('');
arr.push(""); // last position;
for (var i = myString.length; i >= 0; i--) {
if ((x >> i) & 0x01) { // check if bit at position i is 1
arr[i] = myChar + arr[i];
}
}
console.log(arr.join('')); // print out one combination
}
Of course, this works only for small strings of up to 31 characters. For larger strings you'd need to do the binary counting using things other than numbers. Doing it in a string form is one option. Another option is to use a bigint library such as BigInteger.js to do the counting.

How can I avoid counting triplicates as pairs while iterating through an ordered series of letters within an array?

I wrote a simple program to analyze a string to find the word with the greatest amount of duplicate letters within it. It essentially takes a given string, breaks it up into an array of separated words, and then breaks up each separate word into alphabetically sorted groups of individual letters (which are then compared as prev and next, 2 at a time, as the containing array is iterated through). Any two adjacent and matching values found adds one tally to the hash-file next to the word in question, and the word with the most tallied pairs of duplicate letters is returned at the end as greatest. No matching pairs found in any word returns -1. This is what it's supposed to do.
Below, I've run into a problem: If I don't use a REGEXP to replace one of my matched characters, then my code gives false positives as it will count triplicates (eg, "EEE"), as two separate pairs, (eg, "EEE" = "EE & EE", instead of being viewed as "EE, E"). However, if I DO use the REGEXP below to prevent triplicate counts, then doing so breaks my loop mid-stride, and skips to the next word. Is there no way to make this way work? If not, would it be better to employ a REGEXP which deletes all chars EXCEPT the duplicate characters in question, and then perhaps I could divide the .length of each word by 2 to get the number of pairs remaining? Any ideas as to how to solve this would greatly help.
var str = "Helloo aplpplpp pie";
//var str = "no repting letrs";
//var str = "ceoderbyte";
function LetterCountI(str) {
var input = str.split(" ");
console.log(input);
console.log("\n")
var hashObject = {};
var word = "";
var count = 0;
for(var i = 0; i<input.length; i++) {
var currentItem = input[i];
var currentWordIntoChars = currentItem.split("").sort();
console.log(currentWordIntoChars);
var counter = 0;
for(var j=1; j<currentWordIntoChars.length; j++) {
console.log(currentWordIntoChars[j-1] + "=currentChar j-1");
console.log(currentWordIntoChars[j] + "=prev j");
console.log("-");
var final = currentItem;
if(currentWordIntoChars[j-1] == currentWordIntoChars[j]) {
counter++;
hashObject[final] = counter;
//currentWordIntoChars = currentWordIntoChars[j-1].replace(/[a-z]/gi, String.fromCharCode(currentItem.charCodeAt(0)+1));
//HERE REPLACE j-1 with random# or something
//to avoid 3 in a row being counted as 2 pair
//OR use regexp to remove all but pairs, and
//then divide .length/2 to get pairs.
console.log(counter + " === # total char pairs");
}
if(count<hashObject[currentItem]) {
word = final;
count = hashObject[currentItem];
}
}
}
console.log(hashObject);
console.log("\n");
for (var o in hashObject) if (o) return word;
return -1;
}
console.log(LetterCountI(str));
An other way to do it, consists to replace duplicate characters in a sorted word:
var str = "Helloo aplpplpp pie";
function LetterCountI(str) {
var input = str.split(" ");
var count = 0;
var result = -1;
for(var i = 0; i<input.length; i++) {
var nb = 0;
var sortedItem = input[i].split("").sort().join("");
sortedItem.replace(/(.)\1/g, function (_) { nb++ });
if (nb > count) {
count = nb;
result = input[i];
}
}
return result;
}
console.log(LetterCountI(str));
Notes: The replace method is only a way to increment nb using a callback function. You can do the same using the match method and counting results.
if two words have the same number of duplicates, the first word will be returned by default. You can easily change this behaviour with the condition of the if statement.
Whenever you find a match within a word, increment j by 1 to skip comparing the next letter.
var str = "Helloo aplpplpp pie";
//var str = "no repting letrs";
//var str = "ceoderbyte";
function LetterCountI(str)
{
var input = str.split(" ");
console.log(input);
console.log("\n")
var hashObject = {};
var word = "";
var count = 0;
for(var i = 0; i<input.length; i++)
{
var currentItem = input[i];
var currentWordIntoChars = currentItem.split("").sort();
console.log(currentWordIntoChars);
var counter = 0;
for(var j=1; j<currentWordIntoChars.length; j++)
{
console.log(currentWordIntoChars[j-1] + "=currentChar j-1");
console.log(currentWordIntoChars[j] + "=prev j");
console.log("-");
var final = currentItem;
if(currentWordIntoChars[j-1] == currentWordIntoChars[j])
{
counter++;
hashObject[final] = counter;
j++; // ADD HERE
console.log(counter + " === # total char pairs");
}
if(count<hashObject[currentItem])
{
word = final;
count = hashObject[currentItem];
}
}
}
console.log(hashObject);
console.log("\n");
for (var o in hashObject) if (o) return word;
return -1;
}
console.log(LetterCountI(str));

JAVASCRIPT --> Why do I get the error message "Uncaught TypeError: number is not a function "?

I wonder why I get the error message (Uncaught TypeError: number is not a function) , this is my bit of Code:
<script type = "text/javascript">
function dataparse(points)
{
points = points.substr(0, points.length - 1);
var linar = points.split("\n");
// Break each point by line break
var wrkar = [];
var pntar = [];
for (var i = 0; i < linar.length; i++)
{
wrkar = linar[i].split(",", 2);
// Break each point into x and y
pntar.push(new google.maps.LatLng(parseFloat(wrkar[0]), parseFloat(wrkar[1])));
}
return pntar;
}
var cd = [
(30.40545181622765, -9.582610613708539)
(30.405229737948233, -9.577975756530805)
(30.40300892737293, -9.577546603088422)
(30.402268645956614, -9.584241396789594)
];
var df = dataparse(cd);
alert('df');
(30.40545181622765, -9.582610613708539) evaluates to -9.582610613708539
Together with the next line, it's interpreted as
-9.577975756530805(30.405229737948233, -9.577975756530805)
Which of course fails because -9.577... is not a function.
Your dataparse function expects a string, given points.substr(0,points.length - 1)
you initialize cd as an array, but the parser tries to execute (num1, num2) (num3, num4) as a function (see GGG's answer for the reason).
You're points array isn't valid. You will have to use square brackets for the points itself and split them by commas
var cd = [
[30.40545181622765, -9.582610613708539],
[30.405229737948233, -9.577975756530805],
[30.40300892737293, -9.577546603088422],
[30.402268645956614, -9.584241396789594]
];
And with that you will also have to modify (simplify) your dataparse function to handle the array correctly
function dataparse(points) {
var i,
length,
pntar = [];
for (i = 0, length = points.length; i < length; i++) {
pntar.push(new google.maps.LatLng(points[i][0], points[i][1]));
}
return pntar;
}
You are getting this, because every number in your brackets is evaluated, you should replace that with the proper argument which your function accepts... since you are using substr, but actually you want to pass an array you should add some code to your function as well :
function dataparse(pairs)
{
for ( i=0; i < pairs.length ; i++ ) {
var wrkar = pairs[i].split(", ",2);
var pntar = [] ;
pntar.push( new google.maps.LatLng(parseFloat(wrkar[0]), parseFloat(wrkar[1])) );
return pntar;
}
}
var cd = [
"30.40545181622765, -9.582610613708539",
"30.405229737948233, -9.577975756530805",
"30.40300892737293, -9.577546603088422",
"30.402268645956614, -9.584241396789594"
];
var df = dataparse(cd);
alert('df');​
here is a jsfiddle http://jsfiddle.net/ptQfc/
1st misake:
var cd = [
(30.40545181622765, -9.582610613708539)
(30.405229737948233, -9.577975756530805)
(30.40300892737293, -9.577546603088422)
(30.402268645956614, -9.584241396789594)
];
Javascript array has to be separated with commas and not with newlines!
The error raises because of cd variable. You use parentheses, however it is not corrent.
Following your dataparse method cd variable should look like:
var cd = "30.40545181622765, -9.582610613708539\n"+
"30.405229737948233, -9.577975756530805\n"+
"30.40300892737293, -9.577546603088422\n"+
"30.402268645956614, -9.584241396789594";
UPDATE: However, you can rewrite your code in the more nice form:
function dataparse(points) {
var pntar = [];
for (var i = 0; i < points.length; i++) {
pntar.push(new google.maps.LatLng(points[i][0], points[i][1]));
}
return pntar;
}
var cd = [
[30.40545181622765, -9.582610613708539],
[30.405229737948233, -9.577975756530805],
[30.40300892737293, -9.577546603088422],
[30.402268645956614, -9.584241396789594]
];
var df = dataparse(cd);
alert(df);
You've misunderstood the syntax required and it's causing a whole host of errors, namely trying to interpret your variables as a function.
In Javascript, the var=[val,val2] construct creates an array. You're trying to treat the contents of the brackets as a string, and split it as such.
A better way to store the array would be:
var cd = [
[30.40545181622765, -9.582610613708539],
[30.405229737948233, -9.577975756530805],
[30.40300892737293, -9.577546603088422],
[30.402268645956614, -9.584241396789594]
];
Your function could then be written as:
function dataparse(linar) {
var wrkar = [] ;
var pntar = [] ;
for (var i = 0; i < linar.length; i++) {
wrkar = linar[i]; // Break each point into x and y
pntar.push( new google.maps.LatLng(parseFloat(wrkar[0]),parseFloat(wrkar[1])));
}
return pntar ;
}
as linar is an array of arrays, each time you loop through the array it sets the next array down as the value of wrkar, which gives you the x and y coordinates.

Categories

Resources