On Tuesday, 5 November 2013 at 17:47:16 UTC, bearophile wrote:
TV[TK] mergeAAs(TK, TV)(TV[TK] aas...) {

It seems even fit for Phobos.

Bye,
bearophile

I have something I would appreciate feedback/criticism on. My first stab at it worked, but had no support for passing in const/immutable.

AA mergeAAs(alias fun = "a + b", AA)(AA[] aas...) if(isAssociativeArray!AA) {
  AA result;
  ...
}

Not sure if this is a good way or if there are better idiomatic ways, but here is what I have got. Any suggestions/improvements to make it more idiomatic would be appreciated. Is there already a DeepUnqual equivalent in phobos?

Thanks
Dan

import std.stdio;
import std.traits;
import std.algorithm;
import std.functional;

template DeepUnqual(T) {
  static if(isAssociativeArray!T) {
alias Unqual!(Unqual!(ValueType!T)[Unqual!(KeyType!T)]) DeepUnqual;
  } else static if(isDynamicArray!T) {
    alias Unqual!(Unqual!(ArrayElementType!T)[]) DeepUnqual;
  } else static if(isPointer!T) {
    alias Unqual!(PointerTarget!T) * DeepUnqual;
  } else {
    alias Unqual!T DeepUnqual;
  }
}

DeepUnqual!AA
mergeAAs(alias fun = "a + b", AA)(AA[] aas...) if(isAssociativeArray!AA) {
  DeepUnqual!AA result;
  if(aas.length) {
    foreach( aa ; aas ) {
      foreach( k , v ; aa ) {
        auto found = k in result;
        if(found) {
          *found = binaryFun!fun(*found, v);
        } else {
          result[k] = v;
        }
      }
    }
  }
  return result;
}

void main() {
  alias double[string] AA;
  AA a = [ "foo":1.1, "bar":2.2 ];
  AA b = [ "foo":1.1, "bard":2.2 ];
  writeln(mergeAAs(a, b));
  writeln(mergeAAs!q{a*b}(a, b));

  {
    const AA ca = a.dup;
    const AA cb = b.dup;
    writeln(mergeAAs(ca,cb));
  }

  {
    immutable AA ia = [ "foo":1.1, "bar":2.2 ];
    immutable AA ib = [ "foo":1.1, "bard":2.2 ];
    writeln(mergeAAs(ia,ib));
  }
}

Reply via email to