Basically, I know how to sort date in array, so I know that it is possible to compare it. But my question is more complex. I have two array and in some cases it can be that one cross each other, and in some it doesn't
My question is how to write dynamic analytic info under this chart in case it cross each other, and in case it does not.
useMemo(() => {
for(var i = 0; i<25; i++){
if(datasetone[I]>datasetwo[i]){return setText(true)}
if(datasetone[i]< datasetwo[i]) {return setText(false);
setRoznica(datasetone[24] - datasetwo[24]);
}
}
}, [datasetone, datasetwo]);
because I know that situation on chart that one is higher then another can happen just one, I want loop through all element of dataset and in case one is higher write statement.
and second quastion is WHEN it happen, you know .flirt or .find which index of dataset is moment of being higher then second one.
This is important because people in my country do not know how to analytic a chart so I can write statement if something happen to tell them.
Related
I'm using list.js to sort a list of items by category. It's easy to make work if each list item only fits in one category, but I am struggling with making this sort correctly if something is assigned more than one category.
This is what I have so far on Codepen.io
Basically, I want to be able to tag things with both beverage AND game. I'm obviously not cycling through the array I've created for each item's categories correctly... So it only ever acknowledges the first item?
There isn't much help in the docs of List.js as to how to use it in this manner. I found an issue the list.js maintainer marked as closed that seemed related, but he basically just told the person to ask for help over here, so that's what I'm trying. https://github.com/javve/list.js/issues/189
I think this is the problem
for (var i=0, j=tryThis.length; i<j; i++) {
if (tryThis[i] == selection) {
return true;
} else {
return false;
}
}
If the first category fits, you return true, but if the first does not fit you immediately return false, preventing any more compares.
You should not return false within the loop but only after the loop, when you know that no category was a match.
===== UPDATE
featureList.filter(function(item) {
This call, does it change the list, or does it return the filtered list?
If it returns the filtered list (as is the usual way) you never saves the returned values?
To save values returned from a filter function you usually just assign the return value.
list = list.filter(function(i) { });
If this works in this case depends on the design of the filter function, but try it.
I would like to run code by testing only the current selection (not the whole document) and I'm having difficulty understanding exactly how the array "app.selection" and its methods work. To start, I use a "for" loop to cycle through each item selected by using:
for(loop = 0; loop < app.selection.length; loop++){
var sel = loop;
}
This works okay, but when I want to get into determining what each item IS, it gets a little weird. For example,
for(txt = 0; txt < app.selection[sel].textFrames.length; txt++){
// do something to each text frame in the selection here.
}
does not work as expected, but
for(img = 0; img < app.selection[sel].allGraphics.length; img++){
// do something to each graphic in the selection here
}
seems to work fine, regardless if the selection includes more than just graphics alone, or whether it is inside or outside a group.
At times, it seems like app.selection[0] is the only way to access the item by itself. In other words, if a text frame is selected, app.selection[0] might be the same as app.document.textFrames[0], in which case it would be redundant (and incorrect) to say
app.document.textFrames[0].textFrames[0]
And yet the same concept on different page items works like a charm. It is quite puzzling to follow. Furthermore, it seems impossible to determine what kind of object the item is. I want to say something along the lines of:
if (app.selection[0] == [object TextFrame])
but that does not seem to work for me. Is there a way to clearly test if the current item is a group, a graphic or a text frame and do different things depending on the result?
app.selection returns an array of Objects, so each item in the array can be of a different type, and the properties and methods available to it will differ. When using the Extendscript Javascript Console you can see what a particular item in the array is on the fly by just typing
app.selection[0]
(or whatever number). The result will be something like [object TextFrame].
While looping through the selection array, you could use app.selection[0].constructor.name to determine the type of each. Or, if you're only interested in certain types,
if (app.selection[i] instanceof TextFrame){}
At that point you'll know more about which properties you can access, depending on the type.
To answer the second part of the question, there isn't an allTextFrames property, but there is an allPageItems property. This returns an array of pageItems (textFrames, groups, etc.), and you can work with it similarly to app.selection. So, if I have three text frames grouped on the first page of my document (and nothing else), I can see that the following are all true:
app.activeDocument.pages[0].textFrames.length == 0;
app.activeDocument.pages[0].allPageItems.length == 4;
app.activeDocument.pages[0].allPageItems[0] instanceof Group;
app.activeDocument.pages[0].allPageItems[1].constructor.name == "TextFrame";
So you could probably cycle through that array if it's more useful to you than the textFrames collection. Just keep in mind that you don't have access to the special collection properties of TextFrames (like everyItem()).
App.selection is indeed an array which every item can be accessed by its index:
var sel = app.selection //May be null on no open documents ! An empty array on no selection with an open document. One to n length array in case of selection.
then given that you selected one or several items, you can reach those objects by its index
sel[0] //This returns the first item of the array. Javascript starts counting at zero.
Once that said if you access, say sel[4] and selection count less than 5 items or column 5 is empty, then you get an undefined value. So you need to carefully check for selection item validity before using it and never presume it will return something.
HTH,
Loic
http://www.ozalto.com
Trying to plan out a function and I wanted to get some input. I am trying to find an efficient way to:
Double the frequency of numbers in an array
Randomize the location of the values in the array.
For example: Lets say I have an array. [0,1,2,3]
first I want to duplicate each number once in a new array. So now we would have something like this.
[0,0,1,1,2,2,3,3].
Lastly, I want to randomize these values so: [0,4,2,3,0,2,3,4]
Eventually, the algorithm I write will need to handle an initial array of 18 digits (so the final, randomized array will be of size 36)
My initial thoughts are to just have a simple while loop that:
Randomly selects a spot in the new array
Checks to see if it is full
-If it is full, then it will select a new spot and check again.
If it is not full, then it will place the value in the new array, and go to the next value.
I am leaving out some details, etc. but I want this algorithm to be fairly quick so that the user doesn't notice anything.
My concern is that when there is only one digit left to be placed, the algorithm will take forever to place it because there will be a 1/36 chance that it will select the empty space.
In general terms, how can I make a smarter and faster algorithm to accomplish what I want to do?
Many thanks!
first I want to duplicate each number once in a new array. So now we would have something like this. [0,0,1,1,2,2,3,3].
That would be rather complicated to accomplish. Since the positions are not relevant anyway, just build [0,1,2,3,0,1,2,3] by
var newArray = arr.concat(arr);
Lastly, I want to randomize these values so: [0,4,2,3,0,2,3,4]
Just use one of the recognized shuffle algorithms - see How to randomize (shuffle) a JavaScript array?. There are rather simple ones that run in linear time and do not suffer from the problem you described, because they don't need to randomly try.
Here is an alternative to the known methods with two arrays, I came up with. It gives relatively good randomization.
var array1=[]
var array=[0,1,2,3,0,1,2,3]
a=array.length;
b=a;
c=b;
function rand(){for (i=0;i<c;i++){
n=Math.floor(Math.random()*b);
array1[i]=array[n]; array.splice(n,1);b--;}
for (i1=0;i1<c;i1++){array[i1]=array1[i1]}
I would like to reduce the size of a javascript array by removing empty nodes at regular intervals (most likely every even or odd node). Is there a simple and efficient way of doing this using built-in javascript or d3.js methods?
Background
For a data-driven, in-browser application, I have an array with indexing representing units on a horizontal time scale.
Initial timescale intervals are an algorithmic best guess, but often, far from all index points have data associated with them. In fact, on the basis of minimum time intervals found, I can often identify a regular pattern of unused elements which can be removed entirely and without impacting any data.
Mapping a timescale to real data is easy enough using d3 selections (empty elements are ignored), but given the size of these arrays and the fact that they are passed around a bit, early removal seems to make sense. Where data does exist, it is very large (a tree), so deletions are perhaps best made in-situ rather than through creation of a new array.
From the array documentation (native and d3.js) I see a couple of possible approaches, but am a little wary both of compatability issues and possible side effects. Perhaps surprisingly, I also found no examples related to array index pattern matching.
To sum up:
the nodes to be deleted follow a pattern (every 2nd node etc)
these nodes are guaranteed empty.
no further dependencies (jQuery etc) thanks.
Many thanks
You can either do it 'by hand' or use the filter function.
The filter function is faster... to write :
function isEmptyNode(x, i ) { return ( i & 1 ) } ; // to keep odd nodes
var myNewArray = myOldArray.filter(isEmptyNode) ;
... but the good old for loop (in-place) is way way way faster :
var dst=0;
for (var i=0, len=myArray.length; i<len ; i++ ) { if (i & 1) myArray[dst++]=myArray[i] }
myArray.length = dst;
You can easily change the if (i & 1) by a if (myTestFunction(i)) to have a more generic filtering.
For the performances, yo can check here that it's more than 100 times faster with a for loop :
http://jsperf.com/filter-odd-items-in-array/2
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.)