Netsuite Javascript Grab Last Array Value - javascript

So I found some info on this site on how to go about grabbing the value of the last index of an array. I have an Array that is of an unknown length. It builds based on a search of results. For example:
var custid = nlapiGetFieldValue('entity');
var custRecord = nlapiLoadRecord('customer', custid);
var itemPriceLineCount = custRecord.getLineItemCount('itempricing');
for (var i = 1; i <= itemPriceLineCount; i++) {
var priceItemId = [];
priceItemId = custRecord.getLineItemValue('itempricing', 'item', i);
if (priceItemId == itemId) {
var histCol = [];
histCol[0] = new nlobjSearchColumn('entity');
histCol[1] = new nlobjSearchColumn('totalcostestimate');
histCol[2] = new nlobjSearchColumn('tranid');
histCol[3] = new nlobjSearchColumn('trandate');
var histFilter = [];
histFilter[0] = new nlobjSearchFilter('entity', null, 'is', custid);
histFilter[1] = new nlobjSearchFilter('item', null, 'is', itemId);
var histSearch = nlapiSearchRecord('invoice', null, histFilter, histCol);
for (var h = 0; h <= histSearch.length; h++) {
var itemRate = new Array();
var histSearchResult = histSearch[h];
itemRate = histSearchResult.getValue('totalcostestimate');
}
}
}
Now when I use:
var last_element = itemRate[itemRate.length - 1];
It gives me the number of digits/placeholders in each element of the array. So as per my example I know my array holds the values of .00 and 31.24 because I put them there for a test. So last_element will result in 3 and 5. How can I grab the value 31.24 or the last element period? I need the value not the number of digits.

var itemRate = new Array();// Not sure what you intend to do with this array
var histSearchResult = histSearch[h];
itemRate = histSearchResult.getValue('totalcostestimate'); // but note `itemRate` is no more an array here. Its a variable having the value of `totalcostestimate` in string format
Now coming to your use case
/* you're trying to get the length of the string value and subtracting -1 from it.
So its very obvious to get those number of digits */
var last_element = itemRate[itemRate.length - 1]; // returns you that index value of the string
If you want to get the last array value of your search i.e histSearch
You may want to do something like this
var last_element = histSearch[histSearch.length-1].getValue('totalcostestimate');
As a side note it is always recommended to validate the returning value from a saved search result. Because on a successful search it returns you an array object on the other hand if no result founds it'll return you null.
//likely to get an error saying can't find length from null
for (var h = 0; h <= histSearch.length; h++) {
}
You can use something like this
// Never enter into the loop if it is null
for (var h = 0; histSearch!=null && h <= histSearch.length; h++) {
}

Related

undefined parameter in js

I am receiving a type error stating that the array testA[i] is undefined whenever I add an input into the html page. I have the array set and i'm trying to add the value of currency to the array using the push method to add to the second part of the array i.e([0][currency])
function Test() {
var testA = [];
for (i = 0; i < 4; i++) {
this.currency = prompt("Please enter a 3-letter currency abbreviation", "");
testA[i].push(currency);
}
}
var index = new Test();
any help as to why the array is undefined would be appreciated.
Note: I have now tried both testA.push(currency) and testA[i] = this.currency, and I still get the same error as before.
Note: the final version should have it loop through 4 different questions asked and each time adding these into an array. At the end of the loop a new variant of the array should be made and the new set of data entered will be added to it. something like
for(i = 0; i < 4; i++) {
testA[i] = i;
for(j = 0; j < 4; j++) {
this.currency = prompt("Please enter a 3-letter currency abbreviation", "");
testA[i][j] = this.currency;
}
}
but at this point in time I'm just trying to get it to work.
You don't use the push method on a index. You use it on the array itself.
Replace this
testA[i].push(currency);
With this
testA.push(currency);
You need to perform push operation on the array directly.
testA.push(currency);
By executing testA[index] you will receive hold value. In JS it will always return undefined, if index is greater than array length.
Because your array is empty as the beginning, you are always receiving undefined.
You are mixing up two different implementation.
Either you use direct assignation.
var testA = new Array(4);
for (i = 0; i < 4; i += 1) {
this.currency = prompt('...', '');
testA[i] = this.currency;
}
Either you push new values into the array.
var testA = [];
for (i = 0; i < 4; i += 1) {
this.currency = prompt('...', '');
testA.push(this.currency);
}
You should use the second one, which is the most simple soluce.
testA[i] = this.currency OR testA.push(this.currency)
Use Modified function below
function Test() {
var testA = [];
for (i = 0; i < 4; i++) {
this.currency = prompt("Please enter a 3-letter currency abbreviation", "");
testA[i] = this.currency; // use this.currency here if you
}
console.log(testA);
}
var index = new Test();

Object Not Maintaining Assigned Values

I am looping through an array to create another array of objects in a modified format.
for (i = 1; i <= 37; i++) { // create 37 boxes for days of the month and nearby dates
room_reservations[i] = {};
var this_date = getDate();
var res_count = 0;
for (var res_index = 0; res_index < reservations.length; res_index++) {
var this_res = reservations[res_index];
// bad assignment location
// res_room = JSON.parse(JSON.stringify(this_res));
if (this_res.checkin <= this_date && this_res.checkout > this_date) {
for (var k = 0; k < this_res.rooms.length; k++) {
var res_room = {};
res_room = JSON.parse(JSON.stringify(this_res));
var this_room = res_room.rooms[k];
res_room.room_index = k;
var traveler_count = this_room.travelers.length;
console.log('traveler_count: ', traveler_count);
res_room.traveler_count = traveler_count;
//traveler_counts[i][res_room.room_name] = traveler_count;
console.log('res_room.traveler_count: ', res_room.traveler_count);
var room_name = this_room.room_name;
console.log('room_name: ', room_name);
res_room.room_name = room_name;
console.log('res_room: ', res_room);
room_reservations[i][res_room.room_name] = res_room;
}
}
}
}
Essentially, I console log the object property traveler_count and get the correct value. But when logging the entire object, the property value is incorrect. It's like it grabs the value from the next loop.
How do I fix this? It is not just the logging. The values being set are wrong in the room_reservations array. For example, I set the attribute name to res_room.room_name and the value to res_room. But the attribute name does not match the value in the object.
Please help. Thx
The problem is that you're using the same res_room object every time through the for (var k) loop. So all the properties in res_room[i] are referring to the same object, which you modify in place. You need to make a copy of the object when you assign it.
room_reservations[i][res_room.room_name] = JSON.parse(JSON.stringify(res_room));

Get the spreadsheet row for a matched value

I'm new to Google Apps Script & I'm trying to make a script for a spreadsheet where I can get the range for the matched value. But there's no function for the cell value like .getRow() or .getRange() or something like this since it's a string value. Here are my codes,
function getInfo() {
var ss1 = sheet1.getSheetByName("Sheet1");
var ss2 = sheet2.getSheetByName("Rates");
var getCountry = ss1.getRange(ss1.getLastRow(), 11).getValue();
var countryRange = ss2.getRange(2, 1, ss2.getLastRow(), 1).getValues();
var getZone = 0;
for (var i = 0; i < countryRange.length; i++) {
if (countryRange[i] == getCountry) {
var getrow_cr = countryRange[i].getRow(); //.getRow() doesn't apply here for string value
getZone = ss2.getRange(getrow_cr + 1, 2).getValue();
}
}
Logger.log(getZone);
}
How can I get the row for the matched string so that I can get the cell value beside the matched cell value?
Your looping variable i starts at 0, which in your case is equivalent to Row 2. To help keep that clear, you could use a named variable to track the first row with data:
var firstrow = 2;
Then when you find a match, the spreadsheet row it's in is i + firstrow.
Updated code:
function getInfo() {
var ss1 = sheet1.getSheetByName("Sheet1");
var ss2 = sheet2.getSheetByName("Rates");
var getCountry = ss1.getRange(ss1.getLastRow(), 11).getValue();
var firstrow = 2;
var countryRange = ss2.getRange(firstrow, 1, ss2.getLastRow(), 1).getValues();
var getZone = 0;
for (var i = 0; i < countryRange.length; i++) {
if (countryRange[i][0] == getCountry) {
var getrow_cr = i + firstrow;
getZone = ss2.getRange(getrow_cr, 2).getValue();
break; // Found what we needed; exit loop
}
}
Logger.log(getZone);
}
Since countryRange is a two-dimensional array with one element in each row, the correct way to reference the value in row i is countryRange[i][0]. If you instead just compare countryRange[i], you are relying on the JavaScript interpreter to coerce the "row" into a String object.

How to test if an id is present in an associative array

I'm am starting in javascript. I'm trying to do a little program that make a statistic upon the number of answer found in a text document.
The situation is this: each question has one id, e.g 8000001 and W if answer is good or R if answer is not good, e.g for an user answer is 8000001W. I have many user so many question of the same id. I want to get number of good answers per questions. E.g id: 800001 have W: 24 and "R": 5.
I have split the answer into id for 8000001 and ans for W or R. I wanted to create an associative table to get question[id]=["W": 0, "R": 0]. But I'm blocking on this. I've tried this code:
var tab = [];
tab[0] = [];
tab[0] = ['8000001W', '8000002W', '8000003W', '8000004R', '8000005W', '8000006R'];
tab[1] = [];
tab[1] = ['8000001R', '8000002W', '8000003R', '8000004W', '8000005R', '8000006W'];
var question = [];
var id;
for (var i=0;i<tab.length;i++) {
document.write("<dl><dt>tableau n° "+i+"<\/dt>");
for (var propriete in tab[i]) {
id = tab[i][propriete].slice(0,7);
var ans = tab[i][propriete].slice(7,8);
question[id] = [];
if(question[id]){
incrementResp.call(rep, ans);
}else{
var rep = initResp(ans);
question[id] = rep;
}
}
document.write("<\/dl>");
}
function incrementResp(type){
this.this++;
}
function initResp(t){
rep = [];
rep.W = (t=='W'?1:0);
rep.R = (t=='R'?1:0);
}
Based on what your want finally, the 'question' should be used as an object literal, defined as question = {} (similar to association array), what you defined here is an array literal. You can check this for more information about different types of literals in JavaScript:
https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Values,_variables,_and_literals#Literals
In terms of your code, you can simple do like this:
if (question[id]) {
question[id][ans] += 1;
}
else {
var rep = initResp(ans);
question[id] = rep;
}
Also your 'initResp' function better to return an object literal 'rep', not as an array literal:
function initResp(t){
var rep = {};
rep.W = (t=='W'?1:0);
rep.R = (t=='R'?1:0);
return rep;
}
For an "associative array" in JavaScript, use a regular object. In the code below, "results" is one of these objects. It has two keys, "W" and "R" that point to numbers starting at 0. Just iterate through your answer arrays and continuously increment the correct key.
There are two ways to access a key in an object: 1) using brackets, 2) using "dot" notation. In the loop I use brackets because 'key' is a variable--it will resolve to "W" or "R" and therefore access the "W" or "R" key in that object. In the final two lines I use dot notation because "W" and "R" are literally the keys I want to access. It would also work if I did this instead: results['W']++ and results['R']++.
var tab = [];
tab[0] = ['8000001W', '8000002W', '8000003W', '8000004R', '8000005W', '8000006R'];
tab[1] = ['8000001R', '8000002W', '8000003R', '8000004W', '8000005R', '8000006W'];
var results = {
W: 0,
R: 0
};
// go through each tab
for (var tabIdx = 0; tabIdx < tab.length; tabIdx++) {
// go through each answer and apppend to an object that keeps the results
for (var i = 0; i < tab[tabIdx].length; i++) {
var answer = tab[tabIdx][i];
// the last character in the string is the "key", (W or R)
var key = answer.slice(-1);
// append to the results object
results[key]++;
}
}
console.log(results);
console.log(results.W); // 7
console.log(results.R); // 5
Open up your development console (on Chrome it's F12) to see the output.
This is how i resolved my problem for associative array.
var tab = [];
tab[0] = ['8000001W', '8000002W', '8000003W', '8000004R', '8000005W', '8000006R'];
tab[1] = ['8000001R', '8000002W', '8000003R', '8000004W', '8000005R', '8000006W'];
tab[2] = ['8000001R', '8000002W', '8000003R', '8000004W', '8000005R', '8000006W'];
var question = {};
for (var tabIndex = 0; tabIndex < tab.length; tabIndex++) {
for (var i = 0; i < tab[tabIndex].length; i++) {
var answer = tab[tabIndex][i];
var id = answer.slice(0,7);
var ans = answer.slice(-1);
if (question[id]) {
question[id][ans] += 1;
}else {
var results = initResp(ans);
question[id] = results;
}
}
}
console.log(question);
function initResp(t) {
var results = [];
results.W = (t === 'W' ? 1 : 0);
results.R = (t === 'R' ? 1 : 0);
//console.log(results);
return results;
}

Javascript Split Array and assign values to variables from NZBMatrix API

Not sure if any of you guys/girls out there that uses the NZBMatrix website API..
In short what I'm trying to do is build an Adobe Air Application,
using JavaScript, AJAX to connect to the API with a search query, this is all good.
When i receive the "request.responseText" back from the API with the 5 results
(can only be 5) I'm having trouble with the JavaScript split function trying to split them all out...
the return string is returned as follows:
NZBID:444027;
NZBNAME:test result 1;
LINK:nzbmatrix.com/nzb-details.php?id=444027&hit=1;
SIZE:1469988208.64;
INDEX_DATE:2009-02-14 09:08:55;
USENET_DATE:2009-02-12 2:48:47;
CATEGORY:TV > Divx/Xvid;
GROUP:alt.binaries.test;
COMMENTS:0;
HITS:174;
NFO:yes;
REGION:0;
|
NZBID:444028;
NZBNAME:another test;
LINK:nzbmatrix.com/nzb-details.php?id=444028&hit=1;
SIZE:1469988208.64; = Size in bytes
etc..etc..
the first Array should split each set of results using |
assign those 5 results to a new array.
the 2nd Array should split each value using :
assign those 12 results to new variables
ie: var nzbidtxt = array1[0]; which would echo like:
document.write(nzbidtxt); // ie: print "NZBID:"
the 3rd Array should split each variable from ;
assign those 12 values to the newly created array
ie: var nzbidValue = array2[0]; which would echo like:
document.write(nzbValue); // ie: print "444027"
so using both arrays I can display a listing of the posts returned..
in a nice usable format..
nzbid: 444027 // this will be used for direct download
nzbName: the name of the nzb
etc..etc..
the function i have been working on is below:
function breakNzbUrlResponse(text)
{
var place = new Array;
var place2 =new Array;
var place3 =new Array;
place[0] = text.indexOf('|');
place2[0] = text.indexOf(':');
place3[0] = text.indexOf(';');
var i = 1;
while(place[i-1] > 0 || i==1) {
place[i] = text.indexOf('|',place[i-1]+1);
place2[i] = text.indexOf(':',place2[i-1]+1);
if(place2[i] == -1)
{
place2[i] = text.length;
}
i++;
}
i=1;
var vars = new Array;
var values = new Array;
var retarray = new Array;
vars[0] = text.substr(0,place[0]);
values[0] = text.substr((place[0]+1),((place2[0]-place[0])-1));
retarray[vars[0]] = values[0];
while(i < (place.length-1) || i==1)
{
vars[i] = text.substr((place2[i-1]+1),((place[i]-place2[i-1])-1));
values[i] = text.substr((place[i]+1),((place2[i]-place[i])-1));
//alert('in loop\r\nvars['+i+'] is: '+vars[i]+'\r\nvalues['+i+'] is: '+values[i]);
retarray[vars[i]] = values[i];
i++;
}
return retarray;
}
This feels and looks like a very long winded process for this type..
all I want to do is basically assign a new variable to each return type
ie
var nzbid = array3[0];
which when split would reference the first line of the return string, NZBID:444027; where the value for NZBID would be 44027..
bit of a book going on, but the more info the better i suppose.
Thanks
Marty
You could probably cut out a significant number of lines of code by further utilizing split() instead of the manual dissections of the entries and using multidimensional arrays instead of repeatedly creating new arrays.
The logic would be:
ResultsArray = split by "|"
FieldArray = Each element of FieldArray split by ";"
ValueArray = Each element of FieldArray split by ":"
2 years later, it's sad that NZBMatrix is still using this horrible format. Here is how you can parse it.
//used to hold temporary key/value pairs
var tempKV = {};
//used to hold the search results
this.searchResults = [];
//The unformatted search results arrive in inResponse
//Remove whitespace and newlines from the input
inResponse = inResponse.replace(/(\r\n|\n|\r)/gm,"");
//search entries are delimited by |
var results = inResponse.split("|");
for(var i = 0; i < results.length; i++){
//key:value pairs in each search result are dlimited by ;
var pair = results[i].split(";");
for(var j = 0; j < pair.length; j++){
//keys and values are delimited by :
var kv = pair[j].split(":");
//normal key:value pairs have a length of 2
if(kv.length == 2){
//make sure these are treated as strings
//tempKV["key"] = "value"
tempKV["" + kv[0]] = "" + kv[1];
}
//Else we are parsing an entry like "http://" where there are multiple :'s
else if(kv.length > 2){
//store the first chunk of the value
var val = "" + kv[1];
//loop through remaining chunks of the value
for(var z = 2; z < kv.length; z++){
//append ':' plus the next value chunk
val += ":" + kv[z];
}
//store the key and the constructed value
tempKV["" + kv[0]] = val;
}
}
//add the final tempKV array to the searchResults object so long
//as it seems to be valid and has the NZBNAME field
if(tempKV.NZBNAME){
this.searchResults[i] = tempKV;
}
//reset the temporary key:value array
tempKV = {};
}
//all done, this.searchResults contains the json search results

Categories

Resources