diff --git a/Project.toml b/Project.toml index e51787c..552e61a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Tables" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" authors = ["quinnj "] -version = "1.10.1" +version = "1.11.0" [deps] DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" @@ -13,7 +13,7 @@ TableTraits = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] -DataAPI = "1" +DataAPI = "1.15" DataValueInterfaces = "1" IteratorInterfaceExtensions = "0.1.1, 1" OrderedCollections = "1" diff --git a/src/Tables.jl b/src/Tables.jl index ddec790..3e0a979 100644 --- a/src/Tables.jl +++ b/src/Tables.jl @@ -1,7 +1,7 @@ module Tables using LinearAlgebra, DataValueInterfaces, DataAPI, TableTraits, IteratorInterfaceExtensions, OrderedCollections - +import DataAPI: rownumber export rowtable, columntable if !hasmethod(getproperty, Tuple{Tuple, Int}) @@ -250,6 +250,7 @@ struct Row{T} <: AbstractRow end Row(x::Row) = x +rownumber(x::Row) = rownumber(x.x) """ Tables.Columns(tbl) diff --git a/src/dicts.jl b/src/dicts.jl index d5d1bf9..1e61af4 100644 --- a/src/dicts.jl +++ b/src/dicts.jl @@ -108,8 +108,10 @@ schema(x::DictRowTable) = Schema(getfield(x, :names), [getfield(x, :types)[nm] f struct DictRow <: AbstractRow names::Vector{Symbol} row::Dict{Symbol, Any} + rownumber::Int end +rownumber(x::DictRow) = getfield(x, :rownumber) columnnames(x::DictRow) = getfield(x, :names) getcolumn(x::DictRow, i::Int) = get(getfield(x, :row), columnnames(x)[i], missing) getcolumn(x::DictRow, nm::Symbol) = get(getfield(x, :row), nm, missing) @@ -121,7 +123,7 @@ Base.eltype(::Type{DictRowTable}) = DictRow function Base.iterate(x::DictRowTable, st=1) st > length(x) && return nothing - return DictRow(x.names, x.values[st]), st + 1 + return DictRow(x.names, x.values[st], st), st + 1 end function subset(x::DictRowTable, inds; viewhint::Union{Bool,Nothing}=nothing, view::Union{Bool,Nothing}=nothing) @@ -131,7 +133,7 @@ function subset(x::DictRowTable, inds; viewhint::Union{Bool,Nothing}=nothing, vi end values = viewhint === true ? Base.view(getfield(x, :values), inds) : getfield(x, :values)[inds] if inds isa Integer - return DictRow(getfield(x, :names), values) + return DictRow(getfield(x, :names), values, inds) else values isa AbstractVector || throw(ArgumentError("`Tables.subset`: invalid `inds` argument, expected `RowTable` output, got $(typeof(ret))")) return DictRowTable(getfield(x, :names), getfield(x, :types), values) diff --git a/src/fallbacks.jl b/src/fallbacks.jl index f0621c0..8392766 100644 --- a/src/fallbacks.jl +++ b/src/fallbacks.jl @@ -19,6 +19,7 @@ end getcolumns(c::ColumnsRow) = getfield(c, :columns) getrow(c::ColumnsRow) = getfield(c, :row) +rownumber(c::ColumnsRow) = getrow(c) # AbstractRow interface Base.@propagate_inbounds getcolumn(c::ColumnsRow, ::Type{T}, col::Int, nm::Symbol) where {T} = getcolumn(getcolumns(c), T, col, nm)[getrow(c)] diff --git a/src/matrix.jl b/src/matrix.jl index b8d0fdb..40d982d 100644 --- a/src/matrix.jl +++ b/src/matrix.jl @@ -31,6 +31,8 @@ struct MatrixRow{T} <: AbstractRow source::MatrixRowTable{T} end +rownumber(x::MatrixRow) = getfield(x, :row) + getcolumn(m::MatrixRow, ::Type, col::Int, nm::Symbol) = getfield(getfield(m, :source), :matrix)[getfield(m, :row), col] getcolumn(m::MatrixRow, i::Int) = diff --git a/src/tofromdatavalues.jl b/src/tofromdatavalues.jl index b3dbb98..18fd90b 100644 --- a/src/tofromdatavalues.jl +++ b/src/tofromdatavalues.jl @@ -60,6 +60,7 @@ struct IteratorRow{T} <: AbstractRow end getrow(r::IteratorRow) = getfield(r, :row) +rownumber(r::IteratorRow) = getrow(r) wrappedtype(::Type{I}) where {T, I<:IteratorRow{T}} = T wrappedtype(::Type{T}) where {T} = T diff --git a/test/runtests.jl b/test/runtests.jl index 25d03c8..6b53203 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -83,7 +83,8 @@ using Test, Tables, OrderedCollections, TableTraits, DataValues, QueryOperators, @test Tables.columnaccess(rows) @test Tables.columns(rows) === nt @test Tables.materializer(rows) === Tables.materializer(nt) - + @test Tables.rownumber(Tables.IteratorRow(row)) == 1 + @test Tables.rowmerge(row; b=200, hey="hello") == (a=1, b=200, hey="hello") @test Tables.rowmerge(row, (hey="hello", a=200)) == (a=200, b=4, hey="hello") @test Tables.rowmerge(row, (hey="hello", a=200), row, (x=:x, y=:y, hey="bye")) == (a=1, b=4, hey="bye", x=:x, y=:y) @@ -826,6 +827,10 @@ end @test isequal(ct.c, [3, missing, missing, 10, 10]) @test isequal(ct.d, [missing, 5, 7, missing, 11]) + for (i,row) in enumerate(drt) + @test Tables.rownumber(row) == i + end + dct = Tables.dictcolumntable(rt) @test isequal(dct.a, [1, missing, 6, 8, 8]) @test isequal(ct.b, Union{Int, Float64, Missing}[2, 4.0, missing, 9, 9])