Named vectors

A named vector is similar to a named tuple, which associate each of its values with a name. Although the names of a named vector cannot be changed, the values can be modified if needed. In contrast to the predefined NamedTuple in Julia, which employs the names as type parameters, we just implement a named vector as a composite struct equipped with the getindex and setindex! functions, with the fieldnames being its names. This simple implementation makes it possible to define your own concrete named vector with any of your preferred type names, and ensures that all instances of a certain concrete named vector share the same names. Therefore, if you are familiar with Python, you will find that our named vector is more qualified to be the counterpart of the namedtuple in Python than the default Julia implementation. Last but not least important, it is also worth noted that a named vector is not a vector, as is similar to that a named tuple is not a tuple in Julia. This results from our basic expectation that a named vector should be more like a tuple other than a vector so that not all operations valid to vectors are also valid to named vectors.

NamedVector

NamedVector defines the abstract type for all concrete named vectors.

Main features include:

  • Values can be accessed or modified either by the . operator or by the [] operator.
  • Comparisons, such as , , ==, , >, <, , are supported. Therefore a vector of named vectors can be sorted by the default sort function.
  • Hash is supported by hash. Therefore, a named vector can be used as the key of a dict or set.
  • Iteration over its fieldnames is supported by keys, over its values is supported by values, over its field-value pairs is supported by pairs.
  • A reverse iteration is also supported.

To subtype it, please note:

  1. A concrete type can be either mutable or immutable as you need, which is different from tuples.
  2. The fields of a concrete type can be of the same type or not. For the former, we denote the named vector as "homogeneous" while for the latter as "inhomogeneous". For homogeneous ones, we define a sub abstract type, HomoNamedVector for further optimization of the default methods. See HomoNamedVector below.
  3. For all concrete subtypes, if inner constructors are defined, the one which has the same interface with the default one must be implemented. Otherwise, some functionalities will not work.
  4. Arithmetic operations, such as +, -, *, /, %, ÷, etc. are not supported. However, the function map is implemented, which can help users do the overloadings of these operations.

HomoNamedVector

HomoNamedVector is the subtype of NamedVector that of all its fields share the same type. Compared to NamedVector, one more default method is implemented with HomoNamedVector, i.e. eltype, which returns the type of its fields. This function ensures the type stability of all the methods that involves an iteration of the field values of a named vector. Therefore, homogeneous named vector are usually more efficient than inhomogeneous ones. Use homogeneous ones as much as possible unless the code efficiency does not matter.

To subtype HomoNamedVector, all the suggestions mentioned in the previous subsection for NamedVector also applies. A recommended template for a subtype is

[mutable] struct YourNamedVector{T} <: HomoNamedVector{T}
    filed1::T
    filed2::T
    ...
end

Manual

Base.:<Method
<(nv1::NamedVector, nv2::NamedVector) -> Bool

Compare two named vectors and judge whether the first is less than the second.

source
Base.:==Method
==(nv1::NamedVector, nv2::NamedVector) -> Bool

Overloaded equivalent operator. Two named vector are equal to each other if and only if their keys as well as their values are equal to each other.

Note

It is not necessary for two named vectors to be of the same concrete type to be equal to each other.

source
Base.convertMethod
convert(::Type{Tuple}, nv::NamedVector) -> Tuple
convert(::Type{NV}, nv::Tuple) where {NV<:NamedVector} -> NV

Convert a named vector to tuple and vice versa.

source
Base.eltypeMethod
eltype(::Type{<:HomoNamedVector{T}}) where T
eltype(nv::HomoNamedVector)

Get the type parameter of a concrete HomoNamedVector.

source
Base.getindexMethod
getindex(nv::NamedVector, index::Int)

Get the value by the [] syntax.

source
Base.hashMethod
hash(nv::NamedVector, h::UInt)

Hash a concrete NamedVector.

source
Base.isequalMethod
isequal(nv1::NamedVector, nv2::NamedVector) -> Bool

Overloaded equivalent operator. Two named vector are equal to each other if and only if their keys as well as their values are equal to each other.

Note

It is not necessary for two named vectors to be of the same concrete type to be equal to each other.

source
Base.islessMethod
isless(nv1::NamedVector, nv2::NamedVector) -> Bool

Compare two named vectors and judge whether the first is less than the second.

source
Base.iterateFunction
iterate(nv::NamedVector, state=1)
iterate(rv::Iterators.Reverse{<:NamedVector}, state=length(rv.itr))

Iterate or reversely iterate over the values of a concrete NamedVector.

source
Base.keysMethod
keys(nv::NamedVector) -> NTuple{length(nv), Symbol}

Iterate over the names.

source
Base.lengthMethod
length(::Type{NV}) where NV<:NamedVector -> Int
length(nv::NamedVector) -> Int

Get the length of a concrete NamedVector.

source
Base.mapMethod
map(f, nvs::NV...) where NV<:NamedVector -> NV

Apply function f elementwise on the input named vectors.

source
Base.pairsMethod
pairs(nv::NamedVector) -> Base.Generator

Iterate over the name-value pairs.

source
Base.replaceMethod
replace(nv::NamedVector; kwargs...) -> typeof(nv)

Return a copy of a concrete NamedVector with some of the field values replaced by the keyword arguments.

source
Base.setindex!Method
setindex!(nv::NamedVector, value, index::Int)

Set the value by the [] syntax if mutable.

source
Base.showMethod
show(io::IO, nv::NamedVector)

Show a concrete NamedVector.

source
Base.valuesMethod
values(nv::NamedVector) -> NTuple{length(nv)}

Iterate over the values.

source
Base.zeroMethod
zero(::Type{NV}) where NV<:NamedVector -> NV
zero(nv::NamedVector) -> typeof(nv)

Get a concrete NamedVector with all values being zero.

source