On 08/31/2012 08:56 AM, Paul wrote:
>> You're welcome. Note that your need of having a structure which is
>> both associative and ordered is, if not unheard-of, at least somewhat
>> uncommon.
>
> I'm parsing program blocks from a proprietary HW/SW system. They provide
> the data in the form of:
>
> Somegroupname/Someblockname
> someparam=value
> anotherparam=value
> ...
> otherparam=value
> end
>
> Somegroupname/Somediffblockname
> someparam=value
> anotherparam=value
> ...
> otherparam=value
> end
>
> Someothergroupname/Someotherblockname
> p1=value
> p2=value
> ...
> px=value
> end
>
> The data is in an ascii text file.
> I need to be able to search it by group/block/parameter.
> I need to be able to maintain group/block order.
> There are ~hundred diff block types where the params and order of params
> are known...though I would rather not create all of these structures or
> lists ahead of time.
>
> My greatest need at this point is to compare two files block by block.
> The blocks may be in diff orders between the files but the params of
> each block type would always be the same in the same order.
>
> So compare groups, blocks within groups, and the values of each param
> for matching group/block names.

Wrap your string[string][string][string] in a user-defined type that provides "the 'in' operator" as well as opIndex and friends. I have started writing this but could not finish it yet:

import std.exception;

class MyTable
{
    string[string][string][string] elements;

    struct Index
    {
        string i0;
        string i1;
        string i2;
    }

    // Enables the 'auto element = myIndex in myTable' syntax
    // (Note: I should have called it Key, not Index.)
    string * opBinary(string op)(Index index)
        if (op == "in")
    {
        string * result = null;

        if (auto table0 = index.i0 in elements) {
            if (auto table1 = index.i1 in *table0) {
                if (auto element = index.i2 in *table1) {
                    result = element;
                }
            }
        }

        return result;
    }

    // Enables 'auto value = myTable[myIndex]'
    ref string opIndex(Index index)
    {
        string * result = this.opBinary!"in"(index);
        enforce(result);

        return *result;
    }

    // Enables 'myTable[myIndex] = value'
    void opIndexAssign(string value, Index index)
    {
        auto existing = this.opIndex(index);

        if (existing) {
            existing = value;

        } else {
            // TODO: ensure that this Index exists
        }
    }

    // TODO: Look up oopIndexUnary and opIndexOpAssign

    string get(Index index, string defaultValue)
    {
        string * result = this.opBinary!"in"(index);
        return result ? *result : defaultValue;
    }
}

void main()
{}

Ali

Reply via email to