Uncaught SyntaxError: Unexpected token var - javascript

That's the error I'm getting from the Google Chrome JavaScript console when I try to run my page. It refers me to the following line
function char_counter(var str)
from the following code
<html>
<head>
<script type="text/javascript">
function text_change_steps()
{
/* STEP 1:
Get text from cells
*/
document.write("Okay, we made it into the function.");
var textStart = document.getElementById("ipt").value;
var textTarget = document.getElementById("tgt").value;
/* STEP 2:
Create 2 maps, one for the letters that need added to textStart,
the other for the letters that need removed from textStart.
EXAMPLE:
If textStart="dude" and textTarget="deck", then following procedure
creates 2 maps, needAdded and needRemoved with key-value pairs
needAdded['c']=1, needAdded['k']=1, needRemoved['u']=1,
and needRemoved['d']=1.
*/
var startChars = char_counter(textStart);
var targetChars = char_counter(textTarget);
var needAdded = map_disjunct(startChars, targetChars);
var needRemoved = map_disjunct(targetChars, startChars);
/* STEP 3:
Display what needs removed and what needs added. Demonstrate process.
*/
if (!is_empty(needRemoved))
{
for (var k in needRemoved)
{
document.write("<p>Need to remove " + needRemoved[k] + " occurence" + (needRemoved[k] > 1 ? "s" : "") + " of <i>" + k + "</i></p>");
}
}
}
function char_counter(var str)
{
/* Given a string str, return a map whose keys are the characters contained
in str and whose values are the corresponding count of each character.
EXAMPLE: Given "aabnsab", return retMap where retMap['a']=3, retMap['b']=2,
retMap['n']=1, retMap['s']=1.
*/
var retMap = {};
for (var k = 0, n = str.length; k < n; ++k)
{
if (str[k] in retMap)
++retMap[str[k]];
else
retMap[str[k]] = 1;
}
return retMap;
}
function map_disjunt(var m1, m2)
{
/* Given maps m1 and m2 with the same key type and with values in the set
{0, 1, 2, ...}, return a map whose keys are every key from m1 that is
in m2 and has a value greater than the corresponding one in m2, or is
in m1 but not m2. The value will be the difference.
EXAMPLE:
If m1 has m1['a']=3 and m1['b']=1 and m2 has m2['a']=1, then retMap['a']=2
and retMap['b']=1.
*/
var retMap = {};
for (var k in m1)
{
var otherCount = (k in m2) ? m2[k] : 0;
if (m1[k] > otherCount)
retMap[k] = m1[k] - otherCount;
}
return retMap;
}
function is_empty(var M)
{
/* Function to determine whether a map is empty
*/
for (var k in M)
if (M.hasOwnProperty(k))
return false;
return true;
}
</script>
<style type="text/css">
</style>
</head>
<body>
<p>Staring word:</p>
<input type="text"t id="ipt"/>
<p>Ending text:</p>
<input type="text" id="tgt"/>
<p><button onclick="text_change_steps()">Show transformation steps</button></p>
</body>
</html>
What's the deal??

Function parameters are local to the function anyway, therefore the var is disallowed there.

Related

Google Script: Multiple conditions per unique ID

The script would count the number of times all VIN numbers are repeated & if all parts have arrived for that VIN Number (Car).
In example, if the VIN number is repeated 5 times then that means there are five parts going to arrive, so then the next step would be to check the arrived column for such VIN if there are 5 "Yes" values then
(VIN number repeated) 5/5 (Number of "Yes" values)
would trigger it to change the [Master] tab Parts Order column to "Yes" for that particular VIN number.
User would manually update the [Parts] tab, arrived column with either "Yes" or leave blank. (If blank then part has not arrived.)
See link for google sheet Template:
https://docs.google.com/spreadsheets/d/1wlGV_QCWpRwmI5FWiOli6lXuzRATy_Goygp3lhtm-Ek/edit?usp=sharing
My attempt:
Special function to get the last value of a column:
function getLastRowSpecial(range){
var rowNum = 0;
var blank = false;
for(var row = 0; row < range.length; row++){
if(range[row][0] === "" && !blank){
rowNum = row;
blank = true;
}else if(range[row][0] !== ""){
blank = false;
};
};
return rowNum;
};
Here I was able to count the number of times each VIN Number appears, but I was unable to count the number of "Yes" values for each unique VIN number. This needs to be dynamic. My approach at the end was not dynamic. Regarding in particular the, var number
Main Script:
/** ---------------------- SPREAD SHEETS ---------------------- **/
var masterS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Master");
var partS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Parts");
/** ----------------- Selecting Range of Cells ----------------- **/
/** ----- Parts Spread Sheet ----- **/
/** VIN to Match */
var vinPartOrderRangeP = partS.getRange("C5:C");
var vinPartValuesP = vinPartOrderRangeP.getValues();
var columnCheckPartVINP = getLastRowSpecial(vinPartValuesP);
var partVINDataRangeP = partS.getRange(5, 3, columnCheckPartVINP, 1);
var partsVinSetP = partVINDataRangeP.getValues();
/** Part Arrived */
var partOrderedRangeP = partS.getRange("N5:N");
var partOrderedValuesP = partOrderedRangeP.getValues();
var partOrderedValuesCorrectLengthP = partOrderedValuesP.splice(0,partsVinSetP.length);
/** Combining VINs with Parts Arrived */
var vinPartsArrivedP = [];
vinPartsArrivedP.push(partsVinSetP,partOrderedValuesCorrectLengthP);
/** ----- Master Spread Sheet ----- **/
/** VIN to Match */
var vinPartOrderRangeM = masterS.getRange("B5:B");
var vinPartValuesM = vinPartOrderRangeM.getValues();
var columnCheckPartVINM = getLastRowSpecial(vinPartValuesM);
var partVINDataRangeM = masterS.getRange(5, 2, columnCheckPartVINM, 1);
var partsVinSetM = partVINDataRangeM.getValues();
/** Part Arrived */
var partPastRangeM = masterS.getRange("I5:I");
var partPastValuesM = partPastRangeM.getValues();
/** ---- For-Loop getting Number of Parts that need to Arrive ---- **/
var vinNumber = [], arrivalPartsRequired = [], prev;
for (var i = 0; i < vinPartsArrivedP[0].length; i++) {
if (vinPartsArrivedP[0][i][0] !== prev) {
vinNumber.push(vinPartsArrivedP[0][i][0]);
arrivalPartsRequired.push(1);
} else {
arrivalPartsRequired[arrivalPartsRequired.length - 1]++;
}
prev = vinPartsArrivedP[0][i][0];
}
console.log('[' + vinNumber[0] + ']','[' + arrivalPartsRequired[0] + ']')
/**
* Now we can say arrivalPartsRequired has the number of Yes's we need
* per each VIN number.
**/
console.log(vinPartsArrivedP[0][3][0])
var number = 0;
var number2 = 0;
var number3 = 0;
var number4 = 0;
var number5 = 0;
for (var j = 0; j < partsVinSetM.length; j++) {
};
for (var k=0; k<vinPartsArrivedP[0].length; k++){
if(vinNumber[0] == vinPartsArrivedP[0][k][0]){
number++
for (var i=0; i<partOrderedValuesP[0].length; i++){
for (var j = 0; j < partOrderedValuesP[0].length; j++) {
if (partOrderedValuesP[i][j] == 'Yes') {
console.log(i);
return i+1;
}
}
return -1;
}
}
if(vinNumber[1] == vinPartsArrivedP[0][k][0]){
number2++
}
if(vinNumber[2] == vinPartsArrivedP[0][k][0]){
number3++
}
if(vinNumber[3] == vinPartsArrivedP[0][k][0]){
number4++
}
if(vinNumber[4] == vinPartsArrivedP[0][k][0]){
number5++
}
};
console.log(number);
console.log(number2);
console.log(number3);
console.log(number4);
console.log(number5);
I believe your goal as follows.
You want to retrieve the values from the columns "C" and "N" from "Parts" sheet, and want to check whether the number of same VIN # at the column "C" and the number of yes at the column "N".
When both numbers are the same, you want to put yes to the column "I" of "Master" sheet.
You want to achieve this using Google Apps Script.
In this case, in order to achieve your goal, how about the following flow?
Retrieve values from "Parts" sheet.
Create an object for checking the number of VIN # and yes.
Create an array for putting to the "Master" sheet.
Put the values to the "Master" sheet.
When this flow is reflected to a sample script, it becomes as follows.
Sample script:
function sample() {
// 1. Retrieve values from "Master" sheet.
var masterS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Master");
var valuesOfParts = partS.getRange("C5:N" + partS.getLastRow()).getValues();
// 2. Create an object for checking the number of `VIN #` and `yes`.
var obj = valuesOfParts.reduce((o, [c,,,,,,,,,,,n]) => {
if (o[c]) {
o[c].c += 1;
if (n == "yes") o[c].yes += 1;
} else {
o[c] = {c: 1, yes: n == "yes" ? 1 : 0};
}
return o;
}, {});
// 3. Create an array for putting to the "Master" sheet.
var partS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Parts");
var rangeOfMaster = masterS.getRange("B5:B" + masterS.getLastRow());
var valuesOfMaster = rangeOfMaster.getValues().map(([b]) => [obj[b] && obj[b].c == obj[b].yes ? "yes" : ""]);
// 4. Put the values to the "Master" sheet.
rangeOfMaster.offset(0, 7).setValues(valuesOfMaster);
}
References:
reduce()
map()

Compare 2 records on screen with javascript

Im looking for a way to compare 2 json records on screen. The way i want is that, i want to show these 2 records side by side and mark the matched or unmatched properties.
Is there a library that does it already, and if not, how can i do it ??
Edit
My goal is to identify the same/different properties & to show them to users with different styles, rather than comparing the objects as a whole.
Someone made a jQuery plugin for this - jQuery.PrettyTextDiff.
https://github.com/arnab/jQuery.PrettyTextDiff
$("input[type=button]").click(function () {
$("#wrapper tr").prettyTextDiff({
cleanup: $("#cleanup").is(":checked")
});
});
JSFiddle
Here is a quick JavaScript function to help you compare the to JSON strings.
First, it checks that they have same number of properties, then compares that they have the same properties (by name) and then it compares the values.
You may want to tweak the value comparison (to allow for undefined or null).
Hope it is a good starter for you.
<script type="text/javascript">
var so = {}; // stackoverflow, of course.
so.compare = function (left, right) {
// parse JSON to JavaScript objects
var leftObj = JSON.parse(left);
var rightObj = JSON.parse(right);
// add object properties to separate arrays.
var leftProps = [];
var rightProps = [];
for(var p in leftObj) { leftProps.push(p); }
for(var p in rightObj) { rightProps.push(p); }
// do they have the same number of properties
if (leftProps.length != rightProps.length) return false;
// is every right property found on the left
for (var r = 0; r < rightProps.length; r++) {
var prop = rightProps[r];
if (leftProps.indexOf(prop) < 0) {
return false;
}
}
// is every left property found on the right
for (var r = 0; r < leftProps.length; r++) {
var prop = leftProps[r];
if (rightProps.indexOf(prop) < 0) {
return false;
}
}
// do the values match?
for (var q = 0; q < leftProps.length; q++) {
var propname = leftProps[q];
var leftVal = leftObj[propname];
var rightVal = rightObj[propname];
if (leftVal != rightVal) {
return false;
}
}
return true;
}
</script>

Ranking an array of string rows by score

I need to create a new array of string rows from an input one. The input array contains just a country name followed by its score. My goal is to recreate this array by adding one more value, which is the rank that the country will appear. Please, check out my skeleton code below.
<!DOCTYPE html>
<html><head><meta charset="UTF-8"></head>
<body>
<button type="button" onclick="myRankFunction( ['AFG\t3,416', 'AUS\t1,414', 'BRA\t2,073', 'JPN\t1,316'] )">Rank</button>
<script>
/*
* The function must return a new rowlist in the format:
* Rank[TAB]Country[TAB]Score
* - notice that the input rowlist DOESN'T contain the "Rank" part in the begining of the row;
* - Rank is an integer number which represents the country's position in the ranking;
* - Score is a float number; more Score means better Rank.
*/
function myRankFunction(rowlist)
{
var newrowlist = [];
var s1 = [], s2 = [];
for(i = 0; i < rowlist.length; i++)
{
s1 = rowlist[i].split("\t");
for(j = 0; j < rowlist.length; j++)
{
// ignores the current row
if(i == j)
{
continue;
}
s2 = rowlist[j].split("\t");
if( s1[1] > s2[1] )
{
}
else if( s1[1] < s2[1] )
{
}
else
{
}
}
}
return newrowlist;
}
</script>
For the example above, the function should return:
['1[TAB]AFG[TAB]3,416',
'2[TAB]BRA[TAB]2,073',
'3[TAB]AUS[TAB]1,414',
'4[TAB]JPN[TAB]1,316']
['AFG\t3,416', 'AUS\t1,414', 'BRA\t2,073', 'JPN\t1,316'].sort(function(a,b){
//retrieving the rank by splitting the entry and return true or false to the sort callback function
//in order to sort by rank 1,2,3 ...
return(a.split('\t')[1]<b.split('\t')[1])
}).map(function(e,i){
//creating a new array from the sorted array
//adding the rank (using the index) - have to add 1, since index starts at 0
return (i+1)+"\t"+e;
})

insert item in javascript array and sort

Let's say I have an array
var test = new Array()
the values in test are 3,6,9,11,20
if I then have a variable
var id = 5
how can I insert 5 between 3 and 6 in the array?
or do I just insert it wherever and then sort the array?
Thanks in advance.
edit:
I have the following code:
function gup( filter )
{
filter = filter.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+filter+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
var queryString = gup("SelectedID");
var hrefs = new Array();
$('.table404').children().children().each(function(){
var link = ($(this).find('a').attr('href'));
var startIndex = link.indexOf(",'");
var endIndex = link.indexOf("');");
if ( startIndex >= 0 && endIndex >= 0 ) {
var linkID = link.substring( startIndex+2, endIndex );
hrefs.push(linkID);
hrefs.push(queryString);
hrefs.sort()
}
alert(hrefs);
});
for each item inserted into the array I get an alert with the ID but for every item I get one 1 (the current queryString value), so the last pop up looks something like
1,1,1,1,1,2,4,6,7,8
Why do I get a new pop up for every item inserted into the array? I get the querystring value once for every other item inserted into the array. What do I have to do to get one pop up with the complete array?
You can use a binary searach to find an insertion point, if you array is large enough:
Below is a quick code with tests. (Warning: not thoroughly tested). Also the array has to be a sorted array.
Once you have an insertion point, just use the Array.splice function to insert at that index.
/**
* Find insertion point for a value val, as specified by the comparator
* (a function)
* #param sortedArr The sorted array
* #param val The value for which to find an insertion point (index) in the array
* #param comparator The comparator function to compare two values
*/
function findInsertionPoint(sortedArr, val, comparator) {
var low = 0, high = sortedArr.length;
var mid = -1, c = 0;
while(low < high) {
mid = parseInt((low + high)/2);
c = comparator(sortedArr[mid], val);
if(c < 0) {
low = mid + 1;
}else if(c > 0) {
high = mid;
}else {
return mid;
}
//alert("mid=" + mid + ", c=" + c + ", low=" + low + ", high=" + high);
}
return low;
}
/**
* A simple number comparator
*/
function numComparator(val1, val2) {
// Suggested b #James
return val1 - val2;
}
// TESTS --------------------------------
var arr = [0,1,3,6,9,11,20];
var idx = findInsertionPoint(arr, 2, numComparator);
arr.splice(idx, 0, 2);
alert(arr); // will alert [0,1,2,3,6,9,11,20]
var arr2 = [0,1,3,6,9,11,20];
var idx2 = findInsertionPoint(arr2, -1, numComparator);
arr2.splice(idx2, 0, -1);
alert(arr2); // will alert [-1,0,1,3,6,9,11,20]
If you have different objects, the only thing you need to do is provide appropriate comparator function.
Or if the array is really small and if you are especially lazy today, you can just do:
test.push(2).sort();
test.push(2); test.sort();

How to parse http query parameters as javascript object?

I am doing something wrong. At the end of this o is empty. I want to pass in a string such as a=3&zz=5 and do o.a and o.zz to retrieve 3 and 5. How do i generate this object?
function MakeIntoFields_sz(sz) {
var kvLs = sz.split('&');
var o = new Array();
for (var kv in kvLs) {
var kvA = kvLs[kv].split('=');
var k = '';
var v = '';
if (kvA.length > 0) {
k = kvA[0];
if (kvA.length > 1)
v = kvA[1];
o[k] = v;
}
}
return o;
};
You could try this simple query string parser:
function ptq(q)
{
/* parse the query */
var x = q.replace(/;/g, '&').split('&'), i, name, t;
/* q changes from string version of query to object */
for (q={}, i=0; i<x.length; i++)
{
t = x[i].split('=', 2);
name = unescape(t[0]);
if (!q[name])
q[name] = [];
if (t.length > 1)
{
q[name][q[name].length] = unescape(t[1]);
}
/* next two lines are nonstandard */
else
q[name][q[name].length] = true;
}
return q;
}
function param() {
return ptq(location.search.substring(1).replace(/\+/g, ' '));
}
In your code you should use:
for (i=0; i<kvLs.length; i++) {
...
}
instead of for ... in
As someone noted, my code does work. I just tested it wrong. I used invalid data from a form and refreshing a page in firefox doesnt update textareas so i kept on testing with bad data.

Categories