def removeKFromList(l, k):
pointer = l
while pointer:
if pointer.next and pointer.next.value == k:
pointer.next = pointer.next.next
else:
pointer = pointer.next
if l and l.value == k:
return l.next
else:
return l
In this code, why do I need to put
pointer = pointer.next
under else? Code does not work if I don't write this under else, but I don't see why.
First realise that pointer is intended to reference the node that precedes the one that might need to be deleted.
Now if we find that the successor of pointer must be deleted, then we get in the if block. In that case the removal of the next node will make the node that comes after that one, the new successor of pointer. As we want to make the check (for deletion) also for that new successor, we should not move pointer, but just leave it like that. In the next iteration we will then correctly determine whether that new successor node must be deleted or not.
If we would have moved pointer with pointer.next, then pointer would refer to the new successor, but it would not be checked for removal (in the next iteration). It would escape the removal check!
Here is a visualisation of what can go wrong when we do pointer = pointer.next in that case.
Input: l = [1,2,2,3], k = 2
l
pointer
↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 2 │ │ value: 3 │
│ next: ───────> │ next: ───────> │ next: ───────> │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
In the first iteration the condition pointer.next.value == k is true, and so the removal is performed with pointer.next = pointer.next.next, resulting in this situation:
l
pointer
↓ ┌────────────────┐
┌───────────┐ │ ┌───────────┐ │ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ │ value: 2 │ └> │ value: 2 │ │ value: 3 │
│ next: ──────┘ │ next: ───────> │ next: ───────> │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
If now we would do pointer = pointer.next, then we get this:
l pointer
↓ ┌────────────────┐ ↓
┌───────────┐ │ ┌───────────┐ │ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ │ value: 2 │ └> │ value: 2 │ │ value: 3 │
│ next: ──────┘ │ next: ───────> │ next: ───────> │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
...and in the next iteration the if condition will not be about that node, but about the next, the one with value 3, and so the second occurrence of 2 will not be deleted!
I am hoping to do something along the lines of pandas merge_asof or QuestDB's ASOF JOIN in Julia. Critically, I also need to apply a group-by operation.
I would be happy to use any of Julia's Table.jl respecting tools. DataFrame's leftjoin get's close, but requires exact key matches, and doesn't do grouping (as far as I can tell). SplitApplyCombine.jl's leftgroupjoin allows you to pass in your own comparison function, but I don't quite see how to use that function to specify the "nearest less than" value, or "nearest greater than" value.
For a simple example where group-bys are not necessary, on two tables left and right, each with a column time, I could use a function like
function find_nearest_before(val, data)
findlast(x -> x <= val, data)
end
[find_nearest_before(t, right.time) for t in left.time]
and this would get me the indices in right to join to left. However, I don't quite see how to put this together with a group-by.
EDIT
Adding an example to make the question more clear. The first table sensor_pings reports when a sensor sees something. The second table in_sensor_FOV tells us what object is actually in a sensor's field of view (FOV) at a given time. Assume a sensor only has one object in its FOV at a time (opposite is not necessarily true).
julia> using TypedTables
julia> sensor_pings = Table(time=[4,5,7,8,9,10,11,13,15,16], sensor_id=[2,1,1,3,2,3,1,2,3,2])
Table with 2 columns and 10 rows:
time sensor_id
┌────────────────
1 │ 4 2
2 │ 5 1
3 │ 7 1
4 │ 8 3
5 │ 9 2
6 │ 10 3
7 │ 11 1
8 │ 13 2
9 │ 15 3
10 │ 16 2
julia> in_sensor_FOV = Table(time=[1.3,2.6,3.8,5.9,7.3,8.0,12.3,14.7], sensor_id=[3,1,2,3,2,2,3,1], object_in_sensor_FOV=[:a,:b,:c,:b,:c,:a,:c,:b])
Table with 3 columns and 8 rows:
time sensor_id object_in_sensor_FOV
┌──────────────────────────────────────
1 │ 1.3 3 a
2 │ 2.6 1 b
3 │ 3.8 2 c
4 │ 5.9 3 b
5 │ 7.3 2 c
6 │ 8.0 2 a
7 │ 12.3 3 c
8 │ 14.7 1 b
The end result of the desired operation would look like
julia> Table(time=[4,5,7,8,9,10,11,13,15,16], sensor_id=[2,1,1,3,2,3,1,2,3,2], object_in_sensor_FOV=[:c,:b,:b,:b,:a,:b,:b,:a,:c,:a])
Table with 3 columns and 10 rows:
time sensor_id object_in_sensor_FOV
┌──────────────────────────────────────
1 │ 4 2 c
2 │ 5 1 b
3 │ 7 1 b
4 │ 8 3 b
5 │ 9 2 a
6 │ 10 3 b
7 │ 11 1 b
8 │ 13 2 a
9 │ 15 3 c
10 │ 16 2 a
It's rather easy to write something like that, you just need to implement double cursor
using TypedTables
using Setfield
sensor_pings = Table(time=[4,5,7,8,9,10,11,13,15,16], sensor_id=[2,1,1,3,2,3,1,2,3,2])
in_sensor_FOV = Table(time=[1.3,2.6,3.8,5.9,7.3,8.0,12.3,14.7], sensor_id=[3,1,2,3,2,2,3,1], object_in_sensor_FOV=[:a,:b,:c,:b,:c,:a,:c,:b])
function mergeasof(t1, t2)
objects = similar(t2.object_in_sensor_FOV, length(t1.time))
d = ntuple(_ -> :z, 3) # :z is a sentinel value, means that there were no objects up to this moment. Can be anything
i2 = 1
# Double cursor
for i1 in axes(t1, 1)
tm1 = t1.time[i1]
# updating `d` to the current time step
while i2 <= length(t2.time)
t2.time[i2] > tm1 && break
#set! d[t2.sensor_id[i2]] = t2.object_in_sensor_FOV[i2]
i2 += 1
end
objects[i1] = d[t1.sensor_id[i1]]
end
return Table(time = t1.time, sensor_id = t1.sensor_id, object_in_sensor_FOV = objects)
end
julia> mergeasof(sensor_pings, in_sensor_FOV)
Table with 3 columns and 10 rows:
time sensor_id object_in_sensor_FOV
┌──────────────────────────────────────
1 │ 4 2 c
2 │ 5 1 b
3 │ 7 1 b
4 │ 8 3 b
5 │ 9 2 a
6 │ 10 3 b
7 │ 11 1 b
8 │ 13 2 a
9 │ 15 3 c
10 │ 16 2 a
it should be rather fast and could be adapted for an arbitrary number of columns (it's just more tedious to right).
Few notes, though
This function expects that tables are sorted over time
It can be adapted to forward search, yet it can be more tedious.
I am using the fact that there are 3 sensors. If the amount of sensors is known beforehand, then it can should be used in ntuple function. If it is unknown or large or indices are arbitrary, then instead of ntuple you can use Dict
d = Dict{Int, Symbol}()
and #set! should be removed
d[t2.sensor_id[i2]] = t2.object_in_sensor_FOV[i2]
and instead of
objects[i1] = d[t1.sensor_id[i1]]
you should use
objects[i1] = get(d, t1.sensor_id[i1], :z)
Here's one way of doing it in DataFrames - this is certainly not the peak of efficiency, but if your data is small enough that you can afford the first leftjoin it might be good enough.
Start by joining in_sensor_FOV onto sensor_pings:
julia> df = leftjoin(sensor_pings, in_sensor_FOV, on = :sensor_id, makeunique = true);
after that you'll have multiple rows for each sensor in sensor_pings, which is where this approach might fail if your data is large.
Then get the time difference:
julia> transform!(df, [:time, :time_1] => ((x, y) -> x - y) => :time_diff);
Now your findlast approach iiuc means we only consider rows with positive time difference:
julia> df = df[df.time_diff .> 0.0, :];
Then we sort by sensor and time diff and pick the first row for each sensor:
julia> res = combine(groupby(sort(df, [:sensor_id, :time_diff]), [:sensor_id, :time]), names(df[:, Not([:sensor_id, :time])]) .=> first .=> names(df[:, Not([:sensor_id, :time])]));
Result (sorted to produce the same output):
julia> sort(select(res, [:time, :sensor_id, :object_in_sensor_FOV]), :time)
10×3 DataFrame
Row │ time sensor_id object_in_sensor_FOV
│ Int64 Int64 Symbol
─────┼────────────────────────────────────────
1 │ 4 2 c
2 │ 5 1 b
3 │ 7 1 b
4 │ 8 3 b
5 │ 9 2 a
6 │ 10 3 b
7 │ 11 1 b
8 │ 13 2 a
9 │ 15 3 c
10 │ 16 2 a
I have a table with this structure:
id | name | batch_id | used
----------------------------------
1 | voucher 1 | 1 | 1
2 | voucher 2 | 1 | 0
3 | voucher 3 | 1 | 1
4 | voucher 4 | 2 | 0
5 | voucher 5 | 3 | 1
And I need to run a query that will group by batch_id and do a sum on the used column.
So the outcome that I need is:
batch_id | sum_used
----------------------------------
1 | 2
2 | 0
3 | 1
This is what I have so far:
TableName.select('DISTINCT ON (batch_id) batch_id')
Which is the same as:
SELECT DISTINCT ON (batch_id) batch_id FROM table_name
Grouping works but I can't get the sum to work.
Can anyone point me in the right direction?
You need to use GROUP BY and SUM aggregation function:
SELECT batch_id, SUM(used::int) AS sum_used
FROM table_name
GROUP BY batch_id
ORDER BY batch_id;
SqlFiddleDemo
Output:
╔═══════════╦══════════╗
║ batch_id ║ sum_used ║
╠═══════════╬══════════╣
║ 1 ║ 2 ║
║ 2 ║ 0 ║
║ 3 ║ 1 ║
╚═══════════╩══════════╝
Alternatively using windowed function:
SELECT DISTINCT batch_id, SUM(used::int) OVER(PARTITION BY batch_id) AS sum_used
FROM table_name
ORDER BY batch_id
SqlFiddleDemo2
Hey you can try this way:
TableName.select('batch_id as batch_id , sum(used) as sum_used').group(:batch_id)
I'm looking to do a table view cell with a photo and wrapping text with auto layout. I've managed a lot with auto layout, but I'm at a loss on how to do this one.
┌─────────────────────────────────────────────────────┐
│ ┌──────────┐ ┌────────────────────────────────────┐ │
│ │ │ │ Title (might wrap) │ │
│ │ │ └────────────────────────────────────┘ │
│ │ Photo │ ┌────────────────────────────────────┐ │
│ │ │ │ Body text. May wrap, may contain │ │
│ │ │ │ multiple lines. │ │
│ │ │ └────────────────────────────────────┘ │
│ └──────────┘ │
└─────────────────────────────────────────────────────┘
As the text expands, I want to keep the photo in the top left and expand the cell. However, the cell should never shrink below the minimum required to show the photo (with margins).
┌─────────────────────────────────────────────────────┐
│ ┌──────────┐ ┌────────────────────────────────────┐ │
│ │ │ │ Title (might wrap) │ │
│ │ │ │ Maybe even to two lines. │ │
│ │ Photo │ └────────────────────────────────────┘ │
│ │ │ ┌────────────────────────────────────┐ │
│ │ │ │ Body text. May wrap, may contain │ │
│ │ │ │ multiple lines. │ │
│ └──────────┘ │ │ │
│ │ Text could require more vertical │ │
│ │ space than the photo. │ │
│ └────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
I'm requiring iOS 8 or later.
I've tried doing this with just the three views listed, and also by putting the left item and right items in two views. Every combination I try seems to ignore the photo's minimum size.
(Btw, for anyone curious: Graphic via Monodraw.)
Try having the following relationships:
Photo:
width = X
height = Y
left = Cell + Z
top = Cell + Z
Title:
left = Photo + Z
right = Cell - Z
top = Cell + Z
the label will auto calculate the height based on content
Body:
Left = Title
Right = Title
Top = Title.Bottom + Z
Cell: (this is the important part)
Bottom >= (equal to or greater than) Body.Bottom + Z
Bottom >= Photo.Bottom + Z
this will force the cell to be, at all times, either taller than the image + offset or taller than the label + offset
In Rails 4.0 I have this table and I want to sort it by the number of occurrences of location_id. In this case the most popular location_id is 3. I want to sort my table in descending order starting with all records with location_id: 3 on the top.
Table Geochecks-
┌────┬─────────┬─────────────┬─────────────────────┬────────────────────┬─────────────────────┐
│ id │ user_id │ location_id │ message │ created_at │ updated_at │
├────┼─────────┼─────────────┼─────────────────────┼────────────────────┼─────────────────────┤
│ 1 ╎ 14 ╎ 2 ╎ Test test t ╎ 2013-07-23 13:3... ╎ 2013-07-23 13:37... │
│ 2 ╎ 12 ╎ 3 ╎ ╎ 2013-07-23 13:5... ╎ 2013-07-23 13:54... │
│ 3 ╎ 15 ╎ 2 ╎ <html lang="en" ... ╎ 2013-07-25 08:5... ╎ 2013-07-25 08:57... │
│ 4 ╎ 12 ╎ 3 ╎ Ohohohooh ╎ 2013-07-25 11:3... ╎ 2013-07-25 11:37... │
│ 5 ╎ 12 ╎ 3 ╎ Pff kjasakljdfas... ╎ 2013-07-25 11:3... ╎ 2013-07-25 11:37... │
│ 6 ╎ 15 ╎ 4 ╎ ╎ 2013-07-25 13:5... ╎ 2013-07-25 13:54... │
│ 7 ╎ 13 ╎ 4 ╎ dasfdasfdasfdasf ╎ 2013-07-25 14:3... ╎ 2013-07-25 14:30... │
│ 8 ╎ 13 ╎ 3 ╎ ╎ 2013-07-25 14:3... ╎ 2013-07-25 14:30... │
│ 9 ╎ 13 ╎ 2 ╎ Test check message ╎ 2013-07-25 14:3... ╎ 2013-07-25 14:31... │
│ 10 ╎ 13 ╎ 5 ╎ asdfdasfdasfdasfa ╎ 2013-07-25 14:4... ╎ 2013-07-25 14:42... │
│ 11 ╎ 16 ╎ 7 ╎ Hohohooh ╎ 2013-07-26 07:5... ╎ 2013-07-26 07:50... │
└────┴─────────┴─────────────┴─────────────────────┴────────────────────┴─────────────────────┘
I know how to count them the by for ex.: Geochecks.where(location_id: 3).count #=> 4 and thought about a loop which will do .where().count requests through the whole table and after that compare the results to find the biggest one, but I am pretty sure that there is a cleverer solution.
Desired output: The desired output should be a list of the location_id's in descending order. In this case it should be: 3, 2, 4, 5, 7
So, doing it with SQL as I pointed out in a comment would be rather complicated and requires good knowledge of SQL. But with a little time in rails c I found a way to do it in Rails!
The result of this query will be Locations not Geochecks, but I don't think it will be a problem for you.
Location.joins(:geochecks).order('COUNT(geochecks.id) DESC').group('location.id')
I think it should work:
Table.find(:all, :order => "location_id_count DESC")