Iterators · Amend · Practice Question
Forward-Fill Nulls with the Previous Value Without Using fills
Question
Given:
l:1.0 0n 20.0 21.0 0n 30.0 33.0 34.0 0nReplace each null with the previous non-null value, without using the built-in fills. You can assume nulls are never consecutive — for every null, the value immediately before it is not itself a null.
Expected result:
1 1 20 21 21 30 33 34 34fSolution
@[l;where 0n=l;:;l -1+where 0n=l]Alternative Solution
?[0n=l;prev l;l]Alternative Solution
(prev l)^lAlternative Solution
{(prev x)^x}/[l]Explanation
@[x;i;:;y] is amend — it sets the items of x at indexes i to the values y, leaving the rest of x untouched. Here:
q)where 0n=l
1 4 8finds the positions of every null, and:
q)l -1+where 0n=l
1 21 34flooks up the value one position before each null (since nulls aren't consecutive, that value is guaranteed non-null). Amend then writes those looked-up values directly into the null positions of l.
The first alternative reaches the same place with a conditional: ?[0n=l;prev l;l] chooses, position by position, between prev l (the previous value) and l itself (unchanged) based on whether the current position is null. The second alternative, (prev l)^l, leans on ^'s fill behaviour directly — filling nulls in l with the corresponding item of prev l. The last alternative is structurally identical to ^ but expressed as Converge over (/), repeatedly filling with the previous value until the result stops changing — robust even if the no-consecutive-nulls assumption doesn't hold, unlike the other three solutions here.