Makla
Makla

Reputation: 10459

ES6 Map or array: need first, last, previuos, next, get (mixing array and Map) in TypeScript

I am using ES6 Map object where keys are Symbol, number or string. I choose map over array because I search items by key a lot and do not want to iterate through array every time when I need to find key. It also suits me key, value pattern.
There will also be a lot of operations where I need next and previous item, occasionally first and last.
Basically it represents Table for Grid.
Currently I use:

Other idea for last is:

let lastKey: any;  //I am using TypeScript with "noImplicitAny": true
for (lastKey of map.keys()) { }

Which one is better?

Are there any other possible solutions? I was also thinking of creating new Object which would have array and Map, but this seems to much or maybe not? Something like this:

class MapArray
{
    map = new Map<string | number | symbol, number>();  //map between keys and array indexes
    array: Array<any> = [];

    constructor(data: Array<any>)
    {
        for (const d in data)
        {
            this.add(d);
        }
    }

    add(value: any)
    {
        this.array.push(value);
        this.map.set(Symbol(), this.array.length - 1);
    }

    next(currentKey: symbol)
    {
        const current = this.map.get(currentKey);

        if (typeof current !== "undefined")
        {
            if (current >= this.array.length - 1)
                return null;    //current is last item
            return this.array[current + 1];
        }
        return this.array[0];   //return first
    }

    previous(currentKey: symbol)
    {
        const current = this.map.get(currentKey);

        if (typeof current !== "undefined")
        {
            if (current == 0)
                return null;    //current is first item
            return this.array[current - 1];
        }
        return this.array[this.array.length - 1];       //return last
    }

    get(key: symbol)
    {
        const index = this.map.get(key);
        if (typeof index !== "undefined")
            return this.array[index];
        return null;
    }

    set(key: symbol, value: any)
    {
        const index = this.map.get(key);
        if (typeof index !== "undefined")
            this.array[index] = value;
        else
            this.add(value);
    }
    //TODO write delete
    //TODO write first/last
    //TODO write generator
}

What do you think? Data will usually be small array (20 items of objects with 3 properties) or larger array with big data (1000 items of objects with 100 or more properties).
Code will largely run on mobiles, so memory usage and performance are important.

Upvotes: 1

Views: 1002

Answers (1)

Bergi
Bergi

Reputation: 664346

I was also thinking of creating a new class which would have Array and Map, but this seems to much?

No, this is the right course of action. It's the only choice to get reasonable performance for indexed access.

The abstraction with all the operations you are using will always be helpful. You can swap out the implementation for something more simple (when it's enough) or more elaborate (when you need it) without changing the code that uses the structure.

Upvotes: 2

Related Questions