Javascript read text file and append values to array - javascript

I have a problem with populating a JavaScript array with a function...
I have some charting software that uses JavaScript. I can input my own values into an array directly to create my desired chart like so:
var data_array=[[0,170],[0,185],[0,179]]
The first value in the array corresponds to sample number (e,g, 0) and the second value corresponds to height (e.g. 170, 185 etc).
This works but I will eventually have a huge list of thousands of values. The height values will be stored in text files. There will be a different file for each sample. The text file will contain a simply list of values separated by lines.
What I need my program to do is open a text file and extract the values and then append them to the data array. So far I have this:
$.get('sample0.txt', function(data, data_array){
var lines=data.split('\n');
for (var i=0; i<lines.length-1;i++){
var item=lines[i];
data_array.push([0,item]);
}
return data_array
}
This doesn't work, although I know it is correctly extracting the values from the text file. I'm not worried about sample number as I can set this for each file. My problem is how to populate the array and make that array exist outside of the function.
I normally code in PHP and I apologize that my knowledge of JavaScript is very basic!

// set this somewhere outside of the $.get callback.
// no need to pass it in as it will be available in that scope.
var data_array = [];
$.get('sample0.txt', function(data) {
var lines=data.split('\n');
for (var i=0; i<lines.length;i++){
var item=lines[i];
data_array.push([0,item]); // modify data_array here
}
// no need to return it
});
Here's a very reduced test: http://jsfiddle.net/4GMMd/
Also note no -1 after lines.length in your for loop, unless your files end with a blank line that you don't want to read.

If I understand your question correctly, you just need to declare the data_array outside the scope of your request function. Plus, your loop is incorrect. It should be i<lines.length not lines.length-1 unless you intend to leave out the last line.
var data_array = [];
$.get('sample0.txt', function(data){
var lines=data.split('\n');
for (var i=0; i<lines.length;i++){
var item=lines[i];
data_array.push([0,item]);
}
}

Related

output individual values from one key JSON jQuery

I'm trying to output values from an array that has one key and multiple values in a JSON file. I've managed to output the values using $.each(), but what happens is that the value is returned as an array, because it is an array! I want to output each value individually so that the output is not an array:
<img src="one-value-output" />
<img src="two-value-output" />
etc...
JSON
var dataJson = "http://www.reneinla.com/kris/scripts/print.json";
The JSON file looks like this:
{
"printImages":[
"http://reneinla.com/kris/images/print/2008-06_KZO_TEN_01.jpg",
"...",
"http://reneinla.com/kris/images/print/2008-06_KZO_TEN_03.jpg"
]
}
JAVASCRIPT
var dataJson = "http://www.reneinla.com/kris/scripts/print.json";
//var dataArr = $.parseJSON(dataJson);
$.getJSON(dataJson, function (data) {
$.each(data, function (k, v) {
console.log( v );
});
});
I'd like to be able to output each value and append it to an src attribute, but wanted to see the console.log output first.
First Question
How do you print out, console.log, all the values from the json file?
Second Question
Is this the right approach to what i'm trying to achieve? I thought I'd use a JSON file because I have 88 values that need to be appended into the DOM. I could make the JSON file into an object, in my js file, but wanted to keep it more organized and efficient. This is still fairly new, so any insight here would be appreciated. Thanks and regards!
EDIT
I was able to get my desired result using this code:
var dataJson = "http://www.reneinla.com/kris/scripts/print.json";
//var dataArr = $.parseJSON(dataJson);
$.getJSON(dataJson, function (data) {
$.each(data, function (k, v) {
var i = 0;
for (i; i < v.length; i++){
console.log( v[i] );
}
});
});
Hooray!
Looking at your JSON, what you have is an object with 1 property, which is an array of strings.
Using developer tools, you should set a breakpoint inside the $.getJSON success callback function to inspect the value of data. You'll see that data is not an array, but that you should actually be going after data.printImages. Otherwise, your code looks OK to me.
Re: Your approach. It seems like a good idea to me. Some day you might change the static .json file out for a server processed file, and you probably wouldn't have to change the client side at all to do that, other than point at a different URL.

How can I store values from one array to another array using 'for' loop

I am trying to create number of arrays like _temp0[],_temp1[],_temp2[] so on and I want to store values of data[] in it.
so value of data[0] goes in array_temp0[] after splitting,
data[1] goes in _temp1[] and so on
to elaborate more-
If value of data[0] is string a,b,c
then array _temp0[] should be
_temp0[0]=a
_temp0[1]=b
_temp0[2]=c
I wrote this function
for(var k=0;k<data.length-1;k++)
{
window['_temp' + k] = new Array();
alert("actual data -- >"+data[k]);
'_temp'+k= data[k].split(',');
alert("data after split -- >"_temp[k]);
}
but it is not working, how do I solve it?
You can do the same using javascript objects. Here is an example of how to do it.
Create an object of name '_temp':
var _temp = {};
When you iterate through 'data' variable then, you can dynamically add attributes to it,say _temp['data0'], _temp['data1'] etc, and every attribute will be an array. For that, you need to write something like:
for(var k=0;k<data.length-1;k++)
{
_temp['data'+k] = data[k].split(',');
}
This will not create the variables identical to what you want. However, this is similar to what you want.
used
window['_temp'+k]= data[k].split(',');
instead of
'_temp'+k= data[k].split(',');
and it worked, thanks to go-oleg

indexOf returning -1 despite object being in the array - Javascript in Google Spreadsheet Scripts

I am writing a script for a Google Docs Spreadsheet to read a list of directors and add them to an array if they do not already appear within it.
However, I cannot seem to get indexOf to return anything other than -1 for elements that are contained within the array.
Can anyone tell me what I am doing wrong? Or point me to an easier way of doing this?
This is my script:
function readRows() {
var column = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Director");
var values = column.getValues();
var numRows = column.getNumRows();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var directors = new Array();
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (directors.indexOf(row) == -1) {
directors.push(row);
} else {
directors.splice(directors.indexOf(row), 1, row);
}
}
for (var i = 2; i < directors.length; i++) {
var cell = sheet.getRange("F" + [i]);
cell.setValue(directors[i]);
}
};
When you retrieve values in Google Apps Script with getValues(), you will always be dealing with a 2D Javascript array (indexed by row then column), even if the range in question is one column wide. So in your particular case, and extending +RobG's example, your values array will actually look something like this:
[['fred'], ['sam'], ['sam'], ['fred']]
So you would need to change
var row = values[i];
to
var row = values[i][0];
As an aside, it might be worth noting that you can use a spreadsheet function native to Sheets to achieve this (typed directly into a spreadsheet cell):
=UNIQUE(Director)
This will update dynamically as the contents of the range named Director changes. That being said, there may well be a good reason that you wanted to use Google Apps Script for this.
It sounds like an issue with GAS and not the JS. I have always had trouble with getValues(). Even though the documentation says that it is a two dimensional array, you can't compare with it like you would expect to. Although if you use an indexing statement like values[0][1] you will get a basic data type. The solution (I hope there is a better way) is to force that object into a String() and then split() it back into an array that you can use.
Here is the code that I would use:
var column = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Director");
var values = column.getValues();
values = String(values).split(",");
var myIndex = values.indexOf(myDirector);
If myDirector is in values you will get a number != -1. However, commas in your data will cause problems. And this will only work with 1D arrays.
In your case: var row = values[i]; row is an object and not the string that you want to compare. Convert all of your values to an array like I have above and your comparison operators should work. (try printing row to the console to see what it says: Logger.log(row))
I ran into a similar problem with a spreadsheet function that took a range as an object. In my case, I was wanting to do a simple search for a fixed set of values (in another array).
The problem is, your "column" variable doesn't contain a column -- it contains a 2D array. Therefore, each value is it's own row (itself an array).
I know I could accomplish the following example using the existing function in the spreadsheet, but this is a decent demo of dealing with the 2D array to search for a value:
function flatten(range) {
var results = [];
var row, column;
for(row = 0; row < range.length; row++) {
for(column = 0; column < range[row].length; column++) {
results.push(range[row][column]);
}
}
return results;
}
function getIndex(range, value) {
return flatten(range).indexOf(value);
}
So, since I wanted to simply search the entire range for the existance of a value, I just flattened it into a single array. If you really are dealing with 2D ranges, then this type of flattening and grabbing the index may not be very useful. In my case, I was looking through a column to find the intersection of two sets.
Because we are working with a 2D array, 2dArray.indexOf("Search Term") must have a whole 1D array as the search term. If we want to search for a single cell value within that array, we must specify which row we want to look in.
This means we use 2dArray[0].indexOf("Search Term") if our search term is not an array. Doing this specifies that we want to look in the first "row" in the array.
If we were looking at a 3x3 cell range and we wanted to search the third row we would use 2dArray[2].indexOf("Search Term")
The script below gets the current row in the spreadsheet and turns it into an array. It then uses the indexOf() method to search that row for "Search Term"
//This function puts the specified row into an array.
//var getRowAsArray = function(theRow)
function getRowAsArray()
{
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Get the current spreadsheet
var theSheet = ss.getActiveSheet(); // Get the current working sheet
var theRow = getCurrentRow(); // Get the row to be exported
var theLastColumn = theSheet.getLastColumn(); //Find the last column in the sheet.
var dataRange = theSheet.getRange(theRow, 1, 1, theLastColumn); //Select the range
var data = dataRange.getValues(); //Put the whole range into an array
Logger.log(data); //Put the data into the log for checking
Logger.log(data[0].indexOf("Search Term")); //2D array so it's necessary to specify which 1D array you want to search in.
//We are only working with one row so we specify the first array value,
//which contains all the data from our row
}
If someone comes across this post you may want to consider using the library below. It looks like it will work for me. I was getting '-1' return even when trying the examples provide (thanks for the suggestions!).
After adding the Array Lib (version 13), and using the find() function, I got the correct row!
This is the project key I used: MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T
And the references:
https://sites.google.com/site/scriptsexamples/custom-methods/2d-arrays-library#TOC-Using
https://script.google.com/macros/library/d/MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T/13
Hopefully this will help someone else also.
I had a similar issue. getValues() seems to be the issue. All other methods were giving me an indexOf = -1
I used the split method, and performed the indexOf on the new array created. It works!
var col_index = 1;
var indents_column = main_db.getRange(1,col_index,main_db.getLastRow(),1).getValues();
var values = String(indents_column).split(","); // flattening the getValues() result
var indent_row_in_main_db = values.indexOf(indent_to_edit) + 1; // this worked
I ran into the same thing when I was using
let foo = Sheet.getRange(firstRow, dataCol, maxRow).getValues();
as I was expecting foo to be a one dimensional array. On research for the cause of the apparently weird behavior of GAS I found this question and the explanation for the always two dimensional result. But I came up with a more simple solution to that, which works fine for me:
let foo = Sheet.getRange(firstRow, dataCol, maxRow).getValues().flat();

jqPlot adding 0 value

I'm using the jqPlot library to build charts. I'm using some JS to fetch a JSON file, build a string using values from the JSON file, convert it to a nested array (the only format that jqPlot likes) and then passing to jqplot. jqPlot is reading the arry just fine and is plotting the correct values, but its adding a 0 value at the end.
Here's the string code:
$(function () {
$.getJSON("test.json", chartData);
function chartData(data) {
$.each(data.values, function(index,val){
chartValues += val + ",";
});
};
here's the code that converts it into a nested array:
var temp = new Array();
temp = chartValues.split(',');
var temp2 = new Array(temp);
alert(temp2);
So when temp2 is passed to jqplot it adds a zero, but when I pass it an identical nested array called test that is declared manually, it doesn't add the zero. Here they are for comparison:
var test = [[12,32,21,23,34,43,52,86,25,]];
and here's temp2
[[12,32,21,23,34,43,52,86,25,]]
Any ideas? I'd also appreciate any help with my logic in this, as I feel like I could be creating the nested array more elegantly.
I'm not sure 100% at this point but I think in .....86,25,]] is not right. That might be the reason to add a zero value. Try eliminating this. Another thing is that you can access the data arrays in json files directly using basic access methods. Try at json org.
Removing the last character in the string (before converting to an array) was the solution in this case.
newStr = chartValues.substring(0, chartValues.length-1);

How do I scan JSON with jquery to determine the number of instances of a certain string?

I have some JSON which looks generally like this...
{"appJSON": [
{
"title":"Application Title",
"category":"Business",
"industry":"Retail",
"language":"English",
"tags":[
{"tags":"Sales"},{"tags":"Reporting"},{"tags":"Transportation"},{"tags":"Hospitality"}
],
},
{
"title":"Airline Quality Assurance",
...
...
...]}
I'm looping through JSON to get an array of all of the unique Tags in the data.
My question is, now that I have an array of the different unique Tags in the JSON, how do I best determine the number of times each Tag occurs?
So basically I'm looking to generate a list of all of the tags found in the JSON (which I already have) with the number of times each one occurs (which I don't already have).
Thanks a lot in advance!
I'm assuming when you find a new tag you check to see if you already have that tag somewhere. If you don't you add it to your list. Why not when you check do something like.
var nextTag=//get the next tag in the JSON list
var newTag=true;
for(var i=0;i<tags.length;i++){
if(nextTag === tags[i]){
tagCount[i]++;
newTag=false;
break;
}
}
if(newTag){
tags[tags.length]=nextTag;
tagCount[tagCount.length]=1;
}
This uses two arrays where tagCount[i] is the number of times tag in tags[i] occurs. You could uses an object to do this or however you wanted to.
As an alternative, here's a function which will fill an associative array; the keys will be the tags and the values will be the number of occurrences of that tag.
var tagCounts = []; // Global variable here, but could be an object property or any array you like really
function countTags(tags, tagCounts)
{
$.each(tags, function(i, item) {
var tag = item.tags; // This would change depending on the format of your JSON
if(tagCounts[tag] == undefined) // If there's not an index for this tag
tagCounts[tag] = 0;
tagCounts[tag]++;
});
}
So you can call this function on any number of arrays of tags, passing in your tagCounts (totals) array, and it will aggregate the totals.
var tags1 = [{"tags":"Sales"},{"tags":"Reporting"},{"tags":"Transportation"},{"tags":"Hospitality"}];
var tags2 = [{"tags":"Reporting"},{"tags":"Transportation"}];
var tags3 = [{"tags":"Reporting"},{"tags":"Hospitality"}];
countTags(tags1, tagCounts);
countTags(tags2, tagCounts);
countTags(tags3, tagCounts);
Then you can read them out like so:
for(var t in tagCounts)
// t will be the tag, tagCounts[t] will be the number of occurrences
Working example here: http://jsfiddle.net/UVUrJ/1/
qw3n's answer is actually a more efficient way of doing things, as you're only looping through all the tags onceā€”but unless you have a really huge JSON source the difference isn't going to be noticeable.

Categories

Resources