On 2/10/22 05:42, novice2 wrote:
> On Thursday, 10 February 2022 at 12:08:07 UTC, tastyminerals wrote:
>> I meant a different thing though. I am looking for
>> `mydic.update(another_dic)` analogue where `{"a": 1, "b": 2}` update
>> `{"c": 3, "a": -1}` becomes `{"a":-1, "b": 2, "c": 3}`.
>
> you need "merge"?
> https://forum.dlang.org/post/fhhuupczjnhehxplj...@forum.dlang.org
>

Probably but Python's update updates the original dictionary. I came up with the following function:

import std.traits : isAssociativeArray, isImplicitlyConvertible, KeyType, ValueType;

void update(Target, From)(ref Target target, From from)
if (isAssociativeArray!Target &&
    isAssociativeArray!From &&
    isImplicitlyConvertible!(KeyType!From, KeyType!Target) &&
    isImplicitlyConvertible!(ValueType!From, ValueType!Target))
{
  foreach (kv; from.byKeyValue) {
    target[kv.key] = kv.value;
  }
}

unittest {
  auto a = [ "a": 1, "b": 2 ];
  a.update([ "c": 3, "a": -1 ]);
  assert(a == [ "a": -1, "b": 2, "c": 3 ]);
}

void main() {
}

Yes, it may look scary to newcomers to D but the template constraint is just for improved usability. (Still, I suspect it's not complete.) Otherwise, the following is the same thing:

void update(Target, From)(ref Target target, From from) {
  foreach (kv; from.byKeyValue) {
    target[kv.key] = kv.value;
  }
}

'ref' is needed there to work with null AAs. Without 'ref', the following would not work:

  int[string] aa;
  aa.update([ "x" : 42 ]);

'aa' would be null! Welcome to AA reference semantics. :)

Ali

Reply via email to