Adding values to each row in Swift but not when row is dequeued & reused - swift

I'm getting info from a GPS service giving an array of addresses, each one containing a duration of time in seconds. So from point A to Point B the time duration is 250 seconds and from Point B to C 100 seconds. It does not add the times together to make a complete route time, I have to do that on my own. In above example I would want to see 250 on the first row and 350 on the 2nd row etc. So I am calculating the values together to get the true total for each address by adding them from row to row right inside my table. I grab each address's value from the route's array based on my table index.path row. I populate that into a table and it works beautifuly as so:
let secondsToAdd = Int(self.thisRoute.ttaForSubleg(UInt(indexPath.row)).duration)
duration += secondsToAdd
However when table is scrolled up and down and cells are dequeued and re-queued values are getting added to again and again. I need to reset the duration somewhere to 0 as so:
duration = 0
but I'm stumped as to where!

Without another solution, my only way to do this I think would be to build and maintain an array separately outside the table instead of building it inside the table as I go along. If somebody has a better solution please post!

Related

How to check if the stream of rows has ended

Is there a way for me to know if the stream of rows has ended? That is, if the job is on the last row?
What im trying to do is for every 10 rows do something, my problem are the last rows, for example in 115 rows, the last 5 wont happen but i need them to.
There is no built-in functionality in Talend which tells you if you're on the last row. You can work around this using one of the following:
Get the row count beforehand. For instance, if you have a file, you
can use tFileRowCount to count the number of rows, then when you
process your file, you use a variable for your current row
number, and so you can tell if you've reached the last row. If your
data come from a database, you could either issue a query that
returns the total number of rows beforehand, or modify your main
query to return the total number of rows in an additional column and
use that (using ranking functions).
Do some processing after the subjob has ended: There may be situations
where you need a special processing for the last row, you can achieve
this by getting the last row processed by the previous subjob (which
you have already saved, for instance, by putting a tSetGlobalVar
after your target, when your subjob is done, your variable contains the last written value).
Edit
For your use case, what you could do is first store the result of the API call in memory using tHashOutput, then read it with a tHashInput in order to process it, and you'll know then how many rows you have retrieved using tHashOutput's global variable tHashOuput_X_NB_LINE.

tJavaFlex behaviour when changing loop position

Having some problems in a job, and I suspect it is due to a lack of understanding of tJavaFlex. I am generating 10 rows in this test job, and am generating loop inside a tJavaFlex:
So there are 10 rows coming in, and a loop in the Start and End section. I was expecting that for each row coming in, it would generate 10 identical rows coming out. And that I would see iterations 0,1,2,3....9 for each row.
What I got was this. This looks to me like the entire job is running 10 times, and so I have 100 random values coming through the flow from the tRowGenerator.
If I move the for loop into the Main Code section, I get close to the behaviour I was expecting. I am expecting each row when it comes in to be repeated 10 times, and for 1 row coming in to produce 10 output rows. What I get is this.
But even then my tLogRow is only generating one row for each 10 iterations it seems (look at the tLogRow output after iteration 9 above why not 10 items?). I had thought I would be getting 10 rows for each single row coming in and I would see this in the tLogRow.
What I need to do is take a value from a field coming in, do some reg exp parsing and split into an array, and then for each item in the array create lines in the output flow. i.e. 1 row coming in can be turned into x number of rows coming out using a string.split() method.
Can someone explain the behaviour above, and also advise on the best approach to get one value coming in, do some java manipulation and then generate multiple rows coming out?
Any advice appreciated.
Yes you don't use it correctly.
The initial part is for initiate variable. (executed one time before the first tow)
In the principal you put your loop (executed one time at each row)
In the final you store in global variable for example.(executed one time after the last row)
The principal code will be executed at each row in a tjavaflex. So don't put a for loop inside you can do like the example in the screen.
You tjavaflex comportement is normal. you have ten row so each row the for loop wil be executed 10 time (i<10)
You can use it like :
You dont need to create your own loop.
By putting the for loop in the Start code, your main code will be triggered by the loop and by incoming rows, and it will be executed n*r times.
The behaviour of subjob that contains a tJavaFlex, reveils that component before tJavaFlex is included into its starting code, and the after component is included in the ending code, but that may depend to many conditions like data propagation and trigger type.
start code :
System.out.print("tJavaFlex is starting...");
int i = 0;
Main code :
i++;
System.out.print("tJavaFlex inside Main Code...iteration:"+i);
row8.ITEM_NAME = row7.ITEM_NAME;
row8.ITEM_COUNT = row7.ITEM_COUNT;
End code :
System.out.print("tJavaFlex is ending...");
System.out.print(row7.ITEM_NAME);
Instead of main flow in row5, try using iterate flow to connect tJavaFlex

How to ensure tableView.scrollTo() displays correctly when initializing the table

I am building a screen where the system jumps to rows in a TableView based on error conditions. Not all rows will be touched. My table view can hold approximately 23 rows. When there are less details than that I have no issues.
However when there is more and the first item in error is off the visual flow, I get weird rendering on the first access only.
In this example, I have 63 rows of data, and the first row that needs to be reviewed is like 35.
When the system determines the row it needs to access I jump there by first selecting the row and then scrolling the table to it:
When I initialize the table:
tableView.getSelectionModel().setCellSelectionEnabled(true);
tableView.setItems(sorted);
tableView.setEditable(true);
In the call to select the next row:
int nextRow = determineNextRow();
tableView.getSelectionModel().select(nextRow, columnToEdit);
tableView.scrollTo(nextRow);
At this point the table scrolls off top & bottom. And the display looks like this:
After entering the amount, it drops to the next line and everything looks OK.
I am not quite sure how to correct the initial landing.
Thanks.

Tableau Future and Current References

Tough problem I am working on here.
I have a table of CustomerIDs and CallDates. I want to measure whether there is a 'repeat call' within a certain period of time (up to 30 days).
I plan on creating a parameter called RepeatTime which is a range from 0 - 30 days, so the user can slide a scale to see the number/percentage of total repeats.
In Excel, I have this working. I sort CustomerID in order and then sort CallDate from earliest to latest. I then have formulas like:
=IF(AND(CurrentCustomerID = FutureCustomerID, FutureCallDate - CurrentCallDate <= RepeatTime), 1,0)
CurrentCustomerID = the current row, and the FutureCustomerID = the following row (so it is saying if the customer ID is the same).
FutureCallDate = the following row and the CurrentCallDate = the current row. It is subtracting the future call time from the first call time to measure the time in between.
The goal is to be able to see, dynamically, how many customers called in for a specific reason within maybe 4 hours or 1 day or 5 days, etc. All of the way up until 30 days (this is our actual metric but it is good to see the calls which are repeats within a shorter time frame so we can investigate).
I had a similar problem, see here for detailed version Array calculation in Tableau, maxif routine
In your case, that is basically the same thing as mine, so you could apply that solution, but I find it easier to understand the one I'm about to give, I would do:
1) Create a calculated field called RepeatTime:
DATEDIFF('day',MAX(CallDates),LOOKUP(MAX(CallDates),-1))
This will calculated how many days have passed since the last call to the current. You can add a IFNULL not to get Null values for the first entry.
2) Drag CustomersID, CallDates and RepeatTime to the worksheet (can be on the marks tab, don't need to be on rows or column).
3) Configure the table calculation of RepeatTIme, Compute using Advanced..., partitioning CustomersID, Adressing CallDates
Also Sort by Field CallDates, Maximum, Ascending.
This will guarantee the table calculation works properly
4) Now you have a base that you can use for what you need. You can either export it to csv or mdb and connect to it.
The best approach, actually, is to have this RepeatTime field calculated outside Tableau, on your database, so it's already there when you connect to it. But this is a way to use Tableau to do the calculation for you.
Unfortunately there's no direct way to do this directly with your database.

What is the best way to reorder 1000 rows at one shot

I have 1000 records in a table which holds position field starting from 1 to 1000. Now I want to implement the reorder functionality for 1000 records. Suppose, If I move the 1000th record to 1st position then the 1st record should move to 2nd positon, 2nd record move to 3rd position and 999th record move to 1000th position.
NOTE: I am showing 20 records per page.
I have implemented the reorder functionality using jqGrid drag and drop plugin. Using this technique it is very simple to update 20 records position at once. On the MySQL side, I will fire 20 update queries to update the 20 records position.
Now, I want to have a textbox field in the position column which holds the current record position. So that, user can move any record to any position by entering the position number in the text field regardless of drag and drop. Suppose, I am in the 50th page and I want to move the 1000th record to 1st position, I will enter the position number in the 1000th position textfield as 1. Once I entered the position number, the reorder logic should take place as I said in the first paragraph.
Now, anyone please tell me how can I update 1000 records at once? and what will be the MySQL load? What is the best way to achieve this functionality?
NOTE: I don't want to fire 1000 update queries (i.e. to avoid MySQL deadlock condition) as I did in the drag and drop functionality.
Thanks for anyone help in advance.
Hundreds of updates is kind of ridiculous.
Try something like this:
UPDATE Records SET
SequenceNumber = SequenceNumber + 1
WHERE SequenceNumber >= #Lowbound AND SequenceNumber <= #UpperBound;
UPDATE Records SET
SequenceNumber = #Lowbound
WHERE ID = #SelectedId;