## ZippedArrays.jl

Zipping Julia arrays together
Author emmt
Popularity
1 Star
Updated Last
5 Months Ago
Started In
November 2020

# Zipping Julia arrays together

`ZippedArrays` is a Julia package to zip several (abstract) arrays together for accessing their elements simultaneously. For instance, assuming that `A`, `B` and `C` are 3 Julia arrays, then:

```using ZippedArrays
Z = ZippedArray(A,B,C)```

builds a zipped array instance `Z` such that the syntax `Z[i]` yields the 3-tuple `(A[i],B[i],C[i])` while the syntax `Z[i] = (a,b,c)` is equivalent to `(A[i],B[i],C[i]) = (a,b,c)`.

Any number of arrays can be zipped together, they must however have the same indices (as returned by the `axes` method).

To build an uninitialized zipped array of size `dims` whose elements are tuples of items of types `T1`, `T2`, etc., call:

`Z = ZippedArray{Tuple{T1,T2,...}}(undef, dims)`

For example:

`Z = ZippedArray{Tuple{Int,Float64}}(undef, 2, 3, 4)`

builds a 3-dimensional array of size `(2,3,4)` and whose elements are 2-tuples of type `Tuple{Int,Float64}`.

Compared to the `zip` function which only provides means to iterate through its arguments, a zipped array can be accessed in random order and for reading and writing. This makes zipped arrays useful for multi-key sorting. For instance:

```sort!(ZippedArray(A,B);
lt = (x,y) -> ifelse(x == y, x < y, x < y))```

will sort in-place vectors `A` and `B` such that the values in `A` are in increasing order and, in case of equality, the values in `B` are in increasing order.

A zipped array is a simple immutable structure wrapped around the arguments of `ZippedArray` so zipped arrays are almost costless to build. Below is an example of how to build an array `C` whose elements are pairs of values from `A` and `B` and a zipped array `Z` also built from `A` and `B`:

```using ZippedArrays
n = 10_000
A = rand(Float64, n)
B = rand(Int64, n)
C = [(A[i],B[i]) for i in 1:n]
Z = ZippedArray(A,B)
C == Z # yields true```

The comparison `C == Z` shows that the two arrays are virtually the same (although not the same object, that is `C !== Z`). Building `Z` however requires no copy of array elements and hardly requires additional memory, the sizes of `Z` and `C` are indeed quite different:

```julia> sizeof(Z)
16

julia> sizeof(C)
160000```

These numbers may depend on the architecture (here a 64-bit processor).

Thanks to the in-lining of functions and optimizations, a zipped array may also be faster. For instance, with the arrays `C` and `Z` defined above:

```using BenchmarkTools
function sum_first(A::AbstractArray{<:Tuple})
s = 0.0
@inbounds @simd for i in eachindex(A)
s += first(A[i])
end
return s
end
@btime sum_first(\$C) # 1.615 μs (0 allocations: 0 bytes)
@btime sum_first(\$Z) # 643.983 ns (0 allocations: 0 bytes)```

### Required Packages

No packages found.