Removing commas from multidimensional arrays - google-apps-script

I'm having a bit of trouble removing commas from an array when I go to write it to a cell in google spreadsheets. array.join(''); doesn't seem to do the trick. I would appreciate any help. Also, anchor[i][j].join('') returns an error.
Here is a bit of code:
anchor[i][j].join('') returns an error
anchor[i].join('') doesn't seem to have an effect.
for (var i=0; i(less than) rangeKW.length-2;i++){
anchor[i] = [];
for (var j=0; j<rangeURL.length;j++){
anchor[i][j] = ahref + rangeKW[i] + ahref1 + rangeURL[j] + "</a>|";
}
}
cell.setValue("{" + anchor);
}

Suppose you have
var x = [[1,2,3],[4,5,6]]
Then either of these lines will give you "123456":
Array.prototype.concat.apply([], x).join('')
x.map(function(a){ return a.join(''); }).join('');
The first one constructs the array [1,2,3,4,5,6] and then joins it. The second one joins each inner array first, constructing ["123", "456"] and then joins that. I think the first one is likely to be a tiny bit more efficient, although we are talking peanuts here, but the second one gives you a bit more control if you want to put something different between rows and columns.
In both cases, this doesn't change the original value in x. You can assign the new value to x if that's what you want.

array.join() works with "normal" arrays, by normal I mean 1 dimension and applies to the array itself, not on an single element (error on [i][j]), beside that I don't really understand what you want to do and how your code is related to your question ...
concerning anchor[i].join('');// doesn't seem to have an effect. I don't know how many elements are in there and how they look like but the syntax is correct. You can also use toString() if you want to make it a CSV string.
EDIT : (thanks for the information in comments.)
I think the easiest way (or at least the most clear) would be to create a couple of new variables that you could log separately to see exactly what happens.
for example
var anchorString = anchor[i].join(); // or toString() they both return strings from 1D arrays
Logger.log(anchorString)
if every index i of anchor have to be in the same cell then write it like this in the i-loop :
var anchorString += anchor[i].join();
Logger.log(anchorString)

Related

HTML Newbie With Nested event.value question

I have an HTML project and I need to nest several operations into one line of code to simplify. I want several fields to be changed based on the selection of another field. Can I "OR" them together within event.value. obviously this isn't working, any suggestions?
else if (event.value==("Bunker"||"Coal Creek"||"Fords Prairie"||"Morton"||"Salkum")){this.getField("CCR").value = "N/A";
this.getField("CBN").value = "N/A";
this.getField("HTR").value = "N/A";
this.getField("SWT").value = "N/A";
this.getField("LTS").value = "N/A";
("Bunker"||"Coal Creek"||"Fords Prairie"||"Morton"||"Salkum") evaluates as "Bunker", so that is the only value you compare event.value to.
If you want to find out if a value matches any in a list, then put the list in an array and use yourArray.includes(value) to see if there is a match.
I don't wanna assume but this looks to be written in JS not HTML. JS if statements evaluate things one by one. To make the code work you would need to have it written as:
(event.value=="Bunker") || (event.value == "Coal Creek") || etc.
There might be a better way to do it where it isn't so tedious that I don't know of.

Using JSON.stringify but SSJS variant in XPages

for an application I am building an administration panel where a power user should be able to check the JSON structure of a selected object.
I would like to display the JSON object in a computed text field but display/format it nicely so it is better human readable, something similar as in pretty print.
Is there any function I could use in SSJS that results in something similar so I can use display json nicely in computed text / editable fields?
Use stringify's third parameter "space":
JSON.stringify(yourObject, null, ' ');
space
A String or Number object that's used to insert white
space into the output JSON string for readability purposes. If this is
a Number, it indicates the number of space characters to use as white
space; this number is capped at 10 if it's larger than that. Values
less than 1 indicate that no space should be used. If this is a
String, the string (or the first 10 characters of the string, if it's
longer than that) is used as white space. If this parameter is not
provided (or is null), no white space is used.
As XPages doesn't support JSON.stringify yet you can include JSON's definition as SSJS resource and use it.
As Knut points out, you can certainly add json2.js to XPages; I've previously used an implementation as Marky Roden's post outlines. This is probably the "safest" way of doing so, from the SSJS side of things.
It does ignore the included fromJson and toJson SSJS methods provided out of the box in XPages. While imperfect, they are functional, especially with the inclusion of Tommy Valand's fix snippet. Be advised, using Tommy's fix does wrap responses to ensure a proper JS object can be parsed by shoving an Array into an object with a values property for the array; so no direct pulling of an Array only.
Additionally, I believe it would be useful to point out that a bean, providing a convenience method or two as wrappers to use either the com.ibm.commons.util.io.json methods to abstract the conversion method, or switching in something like Google GSON, might be more powerful and unified, based on your style of development.
Knut, Eric, I came so far myself already.
function prettyPrint(id) {
var ugly = dojo.byId(id).value;
var obj = $.parseJSON( "[" + ugly + "]" );
var pretty = JSON.stringify(obj, undefined, 4);
dojo.byId(id).innerHTML = pretty;
}
and I call it e.g.
var name = x$('#{id:input-currentObjectCollectionFiltered}').attr("name");
prettyPrint(name);
I tried to make use the x$ function but was not able to make the ID dynamic there e.g.
var ugly = x$('#{id:" + id + "}').val();
not sure why. would be nicer if I just would call prettyPrint('input-currentObjectCollectionFiltered'); and the function would figure it out.
Instead of dojo.byId(id).value I tried:
var ugly=$("#" + id).val();
but things returns and undefined object: I thought jquery would be smarter to work with dynamic id's.
anyway stringify works just fine.

How edge indexing works in graphhopper?

I'm here with a new question.
I'm making a custom algorithm that need precomputed data for the graph edges. I use the AllEdgesIterator like this :
AllEdgesIterator it = graph.getAllEdges();
int nbEdges = it.getCount();
int count = 0;
int[] myData = new int[nbEdges];
while (it.next())
{
count++;
...
}
The first weird thing is that nbEdges is equal to 15565 edges but count is only equal to 14417. How is it possible ?
The second weird thing is when I run my custom A* : I simply browse nodes using the outEdgeExplorer but I get an IndexOutOfBound at index 15569 on myData array. I thought that the edge indexes were included in [0 ; N-1] where N is the number of edges, is it really the case ?
What could be happening here ? By the way, I have disabled graph contraction hierarchies.
Thank you for answering so fast every time !
The first weird thing is that nbEdges is equal to 15565 edges
but count is only equal to 14417. How is it possible ?
This is because of the 'compaction' where unreachable subnetworks are removed, but currently only nodes are removed from the graph the edges are just disconnected and stay in the edges-'array' marked as deleted. So iter.getCount is just an upper limit but the AllEdgeIterator excludes such unused edges correctly when iterating and has the correct count. But using iter.getCount to allocate your custom data array is the correct thing to do.
Regarding the second question: that is probably because the QueryGraph introduces new virtual edges with a bigger edgeId as iter.getCount. Depending on the exact scenario there are different solutions like just excluding or using the original edge instead etc

AS#3 Array is not clearing its contents

Firstly i will briefly explain:
I have 2 Arrays, the first Array:holder, the second Array:Clips.
The first array was dynamic empty boxes as a Grid pattern through a loop pushing each item into an array and adding to the stage// just for the locations x,y
The Second array:Clips are dynamically loaded SWF Movies, 10 all together
These loaded SWF clips are "addChild" into the Holder Array, so these clips will be in the grid pattern and at the same time pushed into the array Clips, for reference example
Clips[1].x = 50 ; // this works fine
so i know my clips are in there, reference correctly. But what icant seem to do is remove all contents from array:Clips
var len:int = Clips.length;
for( var i:int = 0; i < len; i++ ) {
this.removeChild( Clips[i] ) ;
}
i have tried splice aswell with same result just either throws errors or does nothing, either way my items are not deleting / removed off staged.
easy way to explain i load 15 items in an array, everytime the button is pressed i want clear that array and re-populate with another 15 items this happens every 10 seconds for ever..
I can repopulate no problem it will keep loading more stuff over the old content but i want the old content to be cleared
To prevent errors, amend your condition:
if(this.contains(Clips[i]){
this.removeChild(Clips[i]);
}
If it's still not working, you may be removing from the wrong clip, ie not 'this' - try this:
if(Clips[i] != null && Clips[i].parent != null){
Clips[i].parent.removeChild(Clips[i]);
}
(Clips[i] != null part of condition added to check for error cropping up in comments below)
This checks if the clip has a parent specified (if it does, it's inside another clip) and removes it from that clip specifically, not just 'this'.
..and I'd also suggest using a Vector, rather than an Array - you can put any kind of value into an array, so if you put a non-DisplayObject in there you'll get an error when you try to remove if from the stage:
var clips:Vector.<DisplayObject> = new Vector.<DisplayObject>();
rather than:
var clips:Array = [];
Apart from the bulky declaration above, this functions exactly like an array in most respects (functions like push, splice, reference elements with square-bracket notation eg clips[0] etc), but will only let you put certain types of object/variable in it - in this case, DisplayObject. If you try to put an 'int' in there, it won't let you - it also runs a lot faster! They're worth using in any case, but here they may help just in case you've put something else in that array without realising (I've done it plenty of times).
Hope this helps!
Try this. If it works then it means you are trying to remove the child from the wrong parent. That being the case you should be receiving runtime errors. If the following code does not cause errors but there is still content on the screen then you have code somewhere duplicating content. This can happen if the code that does the loading gets called twice.
var len:int = Clips.length;
for( var i:int = 0; i < len; i++ ) {
Clips[i].parent.removeChild(Clips[i]);
}

retrieving a variable value from lower level

well i created some variables in the main stage level, with something like this:
for(i=0,i<10,i++){
var var_name="var_num_"+i;
this[var_name]="some value";
}//<-----------------------------------------------------works
so i get 10 variables named "var_num0", "var_num1", "var_num2" each one with some value.
and i can acces them any where calling this
var second_var=MovieClip(root).var_num0;//<--------------works
my problem comes when i want to call all the variables from a lower level or in another frame or somewhere else using another loop:
var third_var;
for(j=0,j<3,j++){
third_var=this["MovieClip(root).var_num_"+j];//<---------DOSNT WORK
trace(this["MovieClip(root).var_num_"+j]);//<------------returns "undefined"
}
how can i make this work? i tried a lot of things and nothing...
thanks you all
In your case both "root" and "this" are the scope you want to access the vars from. so try this:
var third_var:MovieClip;
for(j = 0; j < 3; j++)
{
third_var = MovieClip(root)[var_num_ + j];
trace(third_var);
}
Also you should have semi-colons in your for loop rather than comers.
I'd like to preface my answer with a suggestion you use a 'Document Class' with AS3 to make things like namespaces and inheritance much clearer. You know exactly where things are accessible when using document based, object oriented programming versus the timeline programming available through the Flash IDE (its only there because of AS1/2). Tut: http://www.kirupa.com/forum/showthread.php?223798-ActionScript-3-Tip-of-the-Day/page14
On to the answer: You are trying to move two levels of inheritance in one set of [] Another way of writing your first "Doesn't work" line is:
this.myMovieClip["var_num"+j"];
You could also use: this["MovieClip"]["var_num"+j];
Basically, you need to take the "MovieClip(root)" out of the string you are using to call your variable because you are passing through two levels of inheritance: this->MovieClip->targetVar
You need to use two periods, a period and a set square bracket or two sets square brackets to move two levels of inheritance. A period . and a set of square brackets [] both accomplish the task of moving one level deeper, so putting the . inside the string used to call up your variable won't work.
Explanation:
The following three examples all return the same variable:
myMovieClip.my_variable
myMovieClip["my_variable"]
var str:String = "my_variable";
myMovieClip[str];