Google Scripts Simple Search - javascript

I want to search a sheet for a value in a sheet, and then return the row and the column where the value was found.
I am well-versed in VBA and have used the .Find function to accomplish this very easily. However, after searching for the last 30 minutes online, I have been stunned to discover that is is so hard to find the code for this extremely simple function. I feel like I am in the twilight zone. Does Javascript really not have anything analogous to .Find? If so, why is this language used so much when VBA appears to be able to accomplish the same tasks in a much more simple manner? Please advise.

I assume you are calling something like mysheet.getDataRange().getValues(), which returns the contents of a google sheet as an array of arrays, eg, [[row1A, row1B], [row2A, row2B]].
With JS, you can get the index of a value in an array using indexOf, which returns the index of the found item or -1 if the item is not in the array. I don't think you can directly search across the two nested arrays. Instead, you could try iterating over the outer array and searching the inner array. Something like this:
// get data from google sheet, doing something like this
var data = mysheet.getDataRange().getValues()
// define our own function
function findItem(data) {
// loop over outer array
for (var i=0; i < data.length; i++) {
var row = data[i]; // get the inner array
var idx = row.indexOf(searchValue); // search for value
// if the value is found, return [row, column]
if (idx > -1) {
return [i, idx];
}
}
// call the function
var res = findItem(data);
var row = res[0];
var col = res[1];

You're comparing apples and oranges. JavaScript and VBA are different languages with different goals. VBA was built to allow it to integrate seamlessly with the MSSQLServer. JavaScript in its native form has no relational-database functionality at all. It's meant more for manipulating web pages through the DOM. (It can do more than that, but that's its primary function.) While VBA can do some of the things Javascript can do, it's a rather clunky way (IMHO) of doing so and narrowly focused on a rather specific set of problems that are tied to very specific software and hardware infrastructures. While that functionality might be nice to have in some cases, most of the JavaScript you see on the web today isn't interested in databases at all.
It's not clear to me what source of data you're trying to connect to but if you are specifically looking for a JavaScript data solution you might want to look into something like MongoDB, and the code libraries that have been developed specifically for that. And there are tons of other JS libraries that are relational-data or database-specific, and you can search places like npm for those. Or you can combine JavaScript with languages that inherently include database functionality, and PHP is an excellent example of that.

Related

In case the example data structure is considered to be a Linked List, how does one write a function which does print out all of its members?

I just started learning Linked List for a technical interview, so this question might seem a little weird.
I was reading an introduction article about Linked List from freecodecamp, and this is what the article
In JavaScript, a linked list looks like this:
const list = {
head: {
value: 6
next: {
value: 10
next: {
value: 12
next: {
value: 3
next: null
}
}
}
}
}
};
My question is, is this a real Linked List? Say I get a question "Print out all the elements in the following linked list, and implement a Linked List yourself." Can I just use the above code? I do know how to use classes to implement a linked list, but I am just wondering if the above code counts as a linked List.
I am asking this question because I only know how to solve the array algorithm question so far.
Say I want to print out all the elements in the array. I will need three steps.
Create an array. // Nums = [1,2,3];
write a function to print it out. // function printNums(Nums){ for (...){console.log(Nums[i]}}
call the function. // printNums(Nums);
So now, I want to do a Linked List version of this. How should I do it?
New Update:
So this is my LinkedList version of printing out all the elements. As a comment mentioned, what I did in the code is in fact a linked list, but it's not called implementation. But what if I just want to test my function? Does the following code make sense to you guys?
My question is, is this a real Linked List?
Yes, it is. You have a collection of data elements, where each data element points to the next.
Say I get a question "Print out all the elements in the following linked list, and implement a Linked List yourself." Can I just use the above code?
When asked to print a specific linked list, we should assume that it is made clear what the exact interface is of that linked list (e.g. nodes are linked via a property called next, and their values are accessed via a property called value). In case of the example list, that is clear. So yes, you could use the piece of code you provided.
The question to implement a Linked List yourself, is a different one. Although it could be understood to define one particular list, that is not how most would interpret that question. It is more likely that this means you should implement a linked list interface: i.e. write code that not only provides easy ways to construct any linked list, but also for using it (find a value, insert a node, delete a node, move a node, ...)
I am just wondering if the above code counts as a linked List.
Yes, the object literal you provided is (one particular instance of) a linked list.
Say I want to print out all the elements in the array. I will need three steps.
Create an array. // Nums = [1,2,3];
Here you make use of a feature of the JavaScript language. Implicitly a constructor is behind this: new Array(1, 2, 3). This constructor is provided as part of the core language. You also get access to methods like push, pop, indexOf, slice, splice, ...etc. All out of the box.
The difference with linked lists is that core JavaScript does not offer an implementation for it. You have to throw your own. Sure, you can use an object literal to create one linked list, but it is quite a verbose way (imagine a list with 100 numbers), and error prone (what if you misspelled next somewhere half way?)
So now, I want to do a Linked List version of this. How should I do it?
If the purpose is only to print the content of a linked list, and nothing else, you can do it like you did. But to get something that offers an interface like you get out of the box for arrays, you would write a class with some useful methods, so you could write:
let myList = LinkedList.from(6, 10, 12, 3);
console.log(...myList.values()); // outputs 6 10 12 3
But what if I just want to test my function? Does the following code make sense to you guys?
Yes, that is fine. If you know that your print function will get either null or an object that has value and next properties, where the next property can be null or another such object, ... then it is fine. In other words: you need to know the interface.
var l = head;
while (l != null) {
console.log(l.value);
l = l.next;
}
Trick is to use while loop until next element is null.
let prev: LinkedListElement<T> | null = this._start;
let finalEl: LinkedListElement<T> = prev;
let counter = 0;
while (prev !== null) {
const retVal = callback(prev, counter);
if (!retVal) {
break;
}
finalEl = prev;
prev = prev.next;
counter++;
}
Let me know if this works.
Also look at this LinkedList class I have created, traverse function is matching the requirement you have.
Class GitHub
NPM package - #dsinjs/linked-list
Complete documentation

Manipulating formatted numbers in a page

I'm working with numerical data I.e. adding, subtracting, present valuing, etc, numbers in a page. However, I format them and print them to the screen. Say I want to add a column of numbers, I have to parse for commas etc. Is there a paradigm to use the actual data, an not have to parse the DOM data? Or should I store both data in the page, but save the numbers as an attribute?
If I understand your question correctly, it sounds like you might be looking for Angular or some other form of two way data binding. Using that framework, you would be able to setup a template to reflect automatically to your "data model" (some javascript construct in memory) and have it update automatically to reflect changes in that model. You can also use "filters" when drawing it to the page to make the raw number display as currency.
create a template. and then pass variables to it, and it spits out html
--mustache (multi types, you want javascript)
--handlerbars.js
=================
MISC javascript code that might be worth while to you.
// would split things up on underscore _
// replace underscore with comma if wanted.
var something = your_something.split('_');
//some for loops
for( var i in something) {
var a = something[i];
}
for (var i = 0; i < something.length; i++) {
var a = something[i];
}
regex, .match, .replace
// are javascript string commands for....
// find(something) and replace with (something) doing.
// other words dealing with decimal points, dollar signs etc..
// and extracting numbers or like.
//dealing with objects and arrays and getting data from them.
something['name'] //= something.name = same thing in many situations.
something[i].name
something[i][x]
something.name.x
var a = '<table>';
a+= '<tr>';
a+= '<td>;
//a = <table><tr><td>
.innerhtml or .append
//used to add stuff to the dom / html stuff already in the something.html file.
json.parse() // may come up
there are way more better examples than i can do out there. but hopefully pickup some keywords that would reveal better internet searches for examples.
normally doing for me... google search "javascript .innerhtml" and open 4 to 10 results i get back and normally find enough to satisfy what i want.
jtables.com i want to say, or datatables.net i also want to say deal with sort spreadhsheet like columns and sorting data that the end user can do.
cookies, localstorage, indexeddb. localstorage most likely easier of the 3 with enough power for simple application and storing information.

each loop on nested JSON children to build a course "chooser" using underscore.js?

Im trying to build a basic site fed with JSON That works as such…
So what I have setup is a table in mysql structured like so…
Where name is the initial list of buttons, then after choosing name you will get each successive choice as needed until you pull up the specific course detail. hopefully I am strait forward so far.
What I have tried so far (and it does work-ish).
so I use getJSON with a little bit of PHP like so...
function getList() {
$.getJSON(serviceURL + 'getProducts.php', function(data) {
products = data.items; });
then I do some $.each with some ifs and some appends...
$.each(products, function(index, product) {
if (product.program === '' && product.platform === '') {
$('#theList').append('<div.....' + course etc.. + ');
};
if (product.program !== '' && product.platform === '') {
something else and so on....
and it works(mostly) but it completely sucks. I have a version of the site right now, that I can click on the product and go through many of the options all the way to a course list and then course detail. I end up having to do addition getJSON with url hashes to get the next level of choices and because I have wait for the data to load I have to create crazy id's for the divs to append to when the data is finally fetched so it appends in the correct place. Like I said, it works, but I know it is the wrong way to do it. To be honest the mysql table is only 110 rows, i could have this all hardcoded a week or two faster than I am figuring this out. But I really need to learn this.
is underscore.js my solution?
so in my travels of the interwebs I discover underscore.js and I try this..
var Sample = _.groupBy(products, 'name');
console.log(Sample);
And I get a beautiful JSON array.
{"Fred":[
{"name":"Fred","Type":"Red","program":"basic","platform":"windows"},
{"name":"Fred","Type":"Red","program":"basic","platform":"osx"},
{"name":"Fred","Type":"Red","program":"basic","platform":"OS X"},
{"name":"Fred","Type":"Red","program":"basic","platform":"osx"},
{"name":"Fred","Type":"Red","program":"basic","platform":"osx"},
{...
and if I do another groupBy on Sample.Fred for Type or program or platform, I get nice little arrays that have the exact data I need. So now I have eliminate the need to do separate getJSON for each level, but I know there must be a better way to do this. Is there a variable for the first level in objects? sample.items doesn't get me anywhere and sample.objects doesn't either, sample.fred works, but then I am going to have to write out each name... sample.fred, sample.Jane, etc... I know that isn't right either.
How do I say…
for each object remove duplicate children (assuming I don't get the courses in my intial getJSON) and then append the values to sequentially nested divs???
As it stands right now I will still have to do a ton of groupBy's and the $.each to append each option to the appropriate div. but I have to believe there is a better and smarter way.
I hope this does't get nailed for being to localized, but I believe it is a basic concept and path I need to do here to be able to filter my way through children getting the list of values I need from particular items.
I realize there are many ways to do this with PHP and a ton of other ways I have never used though of or tried. I don't really want to explore the PHP route as I want to expand my skills in javascript and jquery.
Thanks to any who are willing to help.
It sounds like you might be better going with a full blown class and modeling the relationships. Then you can decide what owns what, and that will give you grouping as needed, as well as letting you easily add functionality and keep you from trying to manage a bunch of arrays.

Select/Order data from two tables

I have two tables holding game data for two different games. For the sake of simplicity, let's say they only share a column called Timestamp (in particular they have a different number of columns). I want to render a list holding information from both tables, simultaneously ordered by Timestamp.
What I'm currently doing works, but I'd take almost any bet that there is a much better way to do this. I'm mostly concerned about performance at some point (mobile app). This is a stub representing the structure – believe me, I know how horrible this looks right now. I just wanted to make it work first, now I'm looking for improvements. ;)
var readyA,
readyB = false;
var dataA,
dataB;
function doLoop () {
setTimeout(renderData, 100);
}
function renderData () {
if (!readyA || !readyB) {
doLoop();
return;
}
var dataAll = dataA.concat(dataB);
dataAll.sort(function (a,b) {
return a['Timestamp'] <= b['Timestamp'];
});
// pass data into a template depending on from which game it is and render it
// ...
}
// wait for both queries to finish
doLoop();
// select data from game A
myDatabaseClass.query('SELECT ... FROM GameA', function (results) {
dataA = new Array(results.rows.length);
for (var i=0; i<results.rows.length; i++) {
dataA[i] = results.rows.item(i);
}
readyA = true;
});
// select data from game B
myDatabaseClass.query('SELECT ... FROM GameB', function (results) {
dataB = new Array(results.rows.length);
for (var i=0; i<results.rows.length; i++) {
dataB[i] = results.rows.item(i);
}
readyB = true;
});
The question would now be if I can somehow simplify this by some kind of UNION or JOIN in the query. Obviously, the Timeout construction is horrible, but that will automatically collapse to a simple callback function if the querying can be done in one query (or at least one transaction – the database class can handle that).
Edit: I did found this ( Pull from two different tables and order ) but this whole NULL AS some_column feels dirty. Is there really no better alternative?
The result of a query always is a single table with a fixed number of columns, so all the SELECTs must have the same number of columns:
SELECT a1, a2, a3, Timestamp FROM GameA
UNION ALL
SELECT b1, b2, NULL, Timestamp FROM GameB
ORDER BY Timestamp
(UNION ALL is faster than UNION because it doesn't try to remove duplicates.)
Your code is pretty good. From the point of view of a SQL hacker like me you're doing the UNION and the ORDER BY on the client side. There's nothing wrong with that. You seem to be doing it almost right. Your "concat" is the client-side equivalent of UNION, and your "sort' is the equivalent of ORDER BY.
You say that the NULL as missing-column construction feels somehow dirty if you use server-side UNION operations. But, obviously to treat two different result sets as the same so you can sort them in order you have to make them conform to each other somehow. Your a['Timestamp'] <= b['Timestamp'] sort-ordering criterion in your sort function is also a scheme for conforming two result sets to each other. It may be lower-performance than using a UNION.
Don't be afraid of using NULL as missing-column to make two result sets in a UNION conform to each other. It's not dirty, and it's not expensive.
Do consider limiting your SELECT operation somehow, perhaps by a range of timestamps. That will allow your system to scale up, especially if you put an index on the column you use to limit the SELECT.
(By the way, your sort function has a mistake in it. sort functions need to return -1, 0, or +1 depending on whether the first item is less than, equal to, or greater than the second one. You're returning a true/false value. That doesn't work properly.)
(You're parallelizing the two queries to the same MySQL instance. That's clever, but probably in truth is a formula for overloading MySQL as your game scales up. Keep in mind that each user of your game has her own machine running Javascript but they all share your MySQL.)

How can I reorder/sort a NodeList in JavaScript?

I have what I think should be a straightforward question; let me quickly explain:
In my JavaScript, food.xml is read in with:
getMenuXml.open("GET","food.xml",false);
getMenuXml.send();
xmlDoc=getMenuXml.responseXML;
xmlFoodList = xmlDoc.getElementsByTagName("food");
so that now I have a NodeList xmlFoodList with all the food elements. Great so far. The problem is I want to sort the nodes based on an element <category> inside. I can read that with:
xmlFoodList[i].getElementsByTagName("category")[0].childNodes[0].nodeValue
Later in my code, the food items are displayed in a list, and as you'd expect, I want food of the same category to be listed together. So, my question is: How can I reorder the nodes in xmlFoodList based on their category?
Notes: I can't change food.xml coming in, and I don't want to edit my later code to do the sorting as the list is populated. I don't want to convert the NodeList to an array, since I'd have to rewrite a lot of later code. Performance isn't actually much of a concern, so feel free to clone/nested loop all you want. Thanks for your time.
You can order the elements of the NodeList, if you convert them to an array first:
var foods = xmlDoc.getElementsByTagName("food");
var foodsArray = Array.prototype.slice.call(foods, 0);
Then you can use the sort method:
foodsArray.sort(function(a,b) {
var aCat = a.getElementsByTagName("category")[0].childNodes[0].nodeValue;
var bCat = b.getElementsByTagName("category")[0].childNodes[0].nodeValue;
if (aCat > bCat) return 1;
if (aCat < bCat) return -1;
return 0;
});
This is highly dependent on your XML schema though - if, for example, you had foods which were in more than one category they would only be sorted by the first category in the code above.
It's a good idea to use a Javascript library to get ready-made functions w.r.t Node List operations such as re-ordering, sorting, foreach etc. I would recommend YUI-3, please refer YUI-3 NodeList .
Take a look at this: Xml, xsl Javascript sorting. Worst case scenario, you transform the data into precisely the same xml, but sorted. As long as you're paying the transformation penalty, you might consider transforming it into a form more useful for whatever the next step is.

Categories

Resources