Skip to content

Commit

Permalink
Document lazy things (JuliaArrays#55)
Browse files Browse the repository at this point in the history
* lazy docs

* Document lazy things

* More care with indexing
  • Loading branch information
piever committed Mar 13, 2019
1 parent de95d68 commit d326c9a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,29 @@ julia> push!(t, (a = 3, b = "z"))
(a = 3, b = "z")
```

### Lazy row iteration

StructArrays also provides a `LazyRow` wrapper for lazy row iteration. `LazyRow(t, i)` does not materialize the i-th row but returns a lazy wrapper around it on which `getproperty` does the correct thing. This is useful when the row has many fields only some of which are necessary. It also allows changing columns in place.

```julia
julia> LazyRow(t, 2).a
2

julia> LazyRow(t, 2).a = 123
123

julia> t
2-element StructArray{NamedTuple{(:a, :b),Tuple{Int64,String}},1,NamedTuple{(:a, :b),Tu
ple{Array{Int64,1},Array{String,1}}}}:
(a = 1, b = "x")
(a = 123, b = "y")
```

To iterate in a lazy way one can simply iterate `LazyRows`:

```julia
julia> map(t -> t.b ^ t.a, LazyRows(t))
2-element Array{String,1}:
"x"
"yy"
```
2 changes: 1 addition & 1 deletion src/StructArrays.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module StructArrays

import Requires
export StructArray, StructVector
export StructArray, StructVector, LazyRow, LazyRows
export collect_structarray, fieldarrays

include("interface.jl")
Expand Down
14 changes: 14 additions & 0 deletions src/lazy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,17 @@ iscompatible(::Type{<:LazyRow{S}}, ::Type{StructArray{T, N, C}}) where {S, T, N,
iscompatible(S, StructArray{T, N, C})

(s::ArrayInitializer)(::Type{<:LazyRow{T}}, d) where {T} = buildfromschema(typ -> s(typ, d), T)

struct LazyRows{T, N, C, I} <: AbstractArray{LazyRow{T, N, C, I}, N}
columns::StructArray{T, N, C}
end
LazyRows(s::S) where {S<:StructArray} = LazyRows(IndexStyle(S), s)
LazyRows(::IndexLinear, s::StructArray{T, N, C}) where {T, N, C} = LazyRows{T, N, C, Int}(s)
LazyRows(::IndexCartesian, s::StructArray{T, N, C}) where {T, N, C} = LazyRows{T, N, C, CartesianIndex{N}}(s)
Base.parent(v::LazyRows) = getfield(v, 1)

Base.size(v::LazyRows) = size(parent(v))
Base.getindex(v::LazyRows{<:Any, <:Any, <:Any, <:Integer}, i::Integer) = LazyRow(parent(v), i)
Base.getindex(v::LazyRows{<:Any, <:Any, <:Any, <:CartesianIndex}, i::Integer...) = LazyRow(parent(v), CartesianIndex(i))

Base.IndexStyle(::Type{<:LazyRows{<:Any, <:Any, <:Any, <:Integer}}) = IndexLinear()
12 changes: 11 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using StructArrays
using StructArrays: LazyRow
import Tables, PooledArrays, WeakRefStrings
using Test

Expand Down Expand Up @@ -416,3 +415,14 @@ end
@test v.a == [i for i in 1:3, j in 1:4]
@test v.b == [j for i in 1:3, j in 1:4]
end

@testset "lazy" begin
s = StructArray(rand(ComplexF64, 10, 10))
rows = LazyRows(s)
@test IndexStyle(rows) isa IndexLinear
@test all(t -> t.re >= 0, s)
@test all(t -> t.re >= 0, rows)
rows[13].re = -12
@test !all(t -> t.re >= 0, s)
@test !all(t -> t.re >= 0, rows)
end

0 comments on commit d326c9a

Please sign in to comment.