commonbox

Unified collections interface to abstract data types and data structures.
https://github.com/chfoo/commonbox/

To install, run:

haxelib install commonbox 0.2.0 

See using Haxelib in Haxelib documentation for more information.

README.md

CommonBox

CommonBox is a unified collections interface to abstract data types and data structures for Haxe.

This library provides a consistent API to common data structures by separating them into 3 concerns: abstract data types, data structure interfaces, and data structure implementations. It allows flexibility for swapping between data structures and reuse of common idioms to collections.

The API is inspired by other containers and collections in other programming languages, such as Python, C#, Java, Scala, and Haskell.

Getting started

Installation

Compatible with Haxe 3.

Install using haxelib:

    haxelib install commonbox

Replacing standard Haxe data structures

Sequences

This section shows how to replace Haxe data structures that manipulate Sequences.

In CommonBox, the equivalent of standard Array is ArrayList. (The name is different to avoid conflicts.) You can easily convert between them.

var array = [1, 2, 3];
var sequence = ArrayList.of(array);

sequence.push(4);
array = sequence.unwrap();
trace(sequence); // [1, 2, 3, 4]

The Haxe Vector, also named Vector in CommonBox, is a fixed length vector. This example shows how to copy the preceding ArrayList to Vector:

var vector = Vector.fromCollection(sequence);
trace(vector); // [1, 2, 3, 4]

A Haxe Vector isn't iterable, but a CommonBox Vector is! In fact, both ArrayList and Vector implement the Sequence abstract data type. The following example contains a function that accepts a sequence of integers adds 1 to them:

function addOne(sequence:Sequence<Int>) {
    for (index in 0...sequence.length) {
        sequence.set(index, sequence.get(index) + 1);
    }
}

var array = ArrayList.of([1, 2, 3]);
var vector = Vector.fromCollection(array);
var list = List.fromCollection(array);

addOne(array);
addOne(vector);
addOne(list);

trace(array); // [2, 3, 4]
trace(vector); // [2, 3, 4]
trace(list); // [2, 3, 4]

In the example above, you may have noticed List. That is another sequence data structure similar to the Haxe List. This is an example of why a unified interface can make collections much easier to use.

Mapings

This section shows how to replace Haxe data structures that manipulate Mappings.

In Haxe, Map is multitype abstract that morphs into an implementation that can handle the particular key type. In CommonBox, AutoMap is provided and works the same way:

var map = new AutoMap<Int,String>();
map.set(100, "hello");

In the example above, map is a CommonBox IntMap which uses Haxe's IntMap as the underlying implementation.

To distinguish between a null value or a missing value, the get() method will return an enum value of haxe.ds.Option:

switch (map.get(100)) {
    case Some(value):
        trace(value);
    case None:
        trace("No value");
}

trace(map.getOnly(100));
// trace(map.getOnly(200)); // NotFoundException
trace(map.getOrElse(200, "default value")); // "default value"

CommonBox also provides a CommonBox HashMap and AnyMap. A CommonBox HashMap is useful for keys that are a composite of data types. An example of using HashMap is in the next section.

AnyMap, however, is unique because it can use anything as its keys unlike a Haxe ObjectMap where only instances of classes may be used. The tradeoff is that its underlying implementation uses linear scanning of arrays, a detail which is covered in the complexity notes in the API documentation.

Equality and comparison checking

By default, equality and comparison checking is done using the Haxe == operator and Reflect.compare method. This can be changed by implementing the interfaces Equatable and Comparable<T> on the objects.

The following example shows how to sort and use XY coordinates as items and keys.

First, we define our Coordinate data structure and implement the Equatable and Comparable interface.

class Coordinate implements Equatable implements Comparable<Coordinate> {
    public var x:Float;
    public var y:Float;

    public function new(x:Float, y:Float) {
        this.x = x;
        this.y = y;
    }

    public function hashCode():Int {
        var hashCode = HashCodeGenerator.getHashCode(x);
        hashCode = HashCodeGenerator.getHashCode(y, hashCode);
        return hashCode;
    }

    public function equals(other:Any):Bool {
        if (other == null || !Std.is(other, Coordinate)) {
            return false;
        }

        var other:Coordinate = cast other;

        return x == other.x && y == other.y;
    }

    public function compareTo(other:Coordinate):Int {
        if (x == other.x) {
            return Reflect.compare(y, other.y);
        } else {
            return Reflect.compare(x, other.x);
        }
    }
}

Now define our array and we can sort various coordinates automatically:

var points = ArrayList.of([
    new Coordinate(10, 5),
    new Coordinate(5, 5),
    new Coordinate(10, -10)
]);

points.sort();
trace(points); // {5, 5}, {10, -10}, {10, 5}

We can also use the data structure as a key in a mapping:

var map = new HashMap<Coordinate,String>();
map.set(new Coordinate(3, 4), "point 1");

var label = map.get(new Coordinate(3, 4));
trace(label); // "point 1"

Data structure summary

The following table describes appropriate uses for common data structures. For details on complexity, see the API documentation.

ADTUse case
SequenceOrdered collection of items
MappingCollection of item pairs
SetCollection of non-repeating items
Sequence TypeStrengthsWeakness
ArrayListRandom accessSlow inserts
VectorFast random accessFixed size
ListFast add/insert/removeSlow random access
DequeFast add/remove on first and last positionSlow random access and inserts
Mapping typeSummary
AutoMapSelect the best map for the keys. Similar to Haxe Map
EnumValueMapSame as Haxe EnumValueMap where keys comparison of Enums
IntMapSame as Haxe IntMap where keys are Ints
ObjectMapSame as Haxe ObjectMap where keys are instances of classes
StringMapSame as Haxe StringMap where keys are compared by Strings
HashMapKeys are instances of Equatable usually a composite of data types
AnyMapLike ObjectMap, but any instance (such as functions) can be used as keys

Development

Running tests

To run tests, use the provided hxml for a target:

    haxe hxml/test.neko.hxml && neko out/neko/test.n
    haxe hxml/test.js.hxml && xdg-open file://$PWD/test.html
    haxe hxml/test.cpp.hxml && ./out/cpp/TestAll-debug

Or supply your own target and arguments:

    haxe test.hxml -python out/python/test.py && python3 out/python/test.py
Contributors
chfoo
Version
0.2.0
Published
today
License
MIT

All libraries are free

Every month, more than thousand developers use haxelib to find, share, and reuse code — and assemble it in powerful new ways. Enjoy Haxe; It is great!

Explore Haxe

Haxe Manual

Haxe Code Cookbook

Haxe API documentation

You can try Haxe in the browser! try.haxe.org

Join us on Github!

Haxe is being developed on GitHub. Feel free to contribute or report issues to our projects.

Haxe on Github