xxxxxxxxxx
import std.stdio;
import std.algorithm;
import std.range;
import std.array;
import std.conv;
import std.json;
void main()
{
// transitive const: no key/value can be modified (no matter how deeply nested)
// note that srv1's type is inferred
const srv1 = [
"acs": ["ver": "1.2.3", "rev": "6f2260d"],
"cms": ["ver": "4.5", "rev": "b17a67e"],
"ots": ["ver": "6.7.80", "rev": "4f487d2"]];
const srv2 = [
"acs": ["ver": "1.2.3", "rev": "6f2260d"],
"cms": ["ver": "5.1", "rev": "2a56c53"],
"vaa": ["ver": "0.7", "rev": "00852cb"]];
string[string][] result;
chain(srv1.keys, srv2.keys) // lazy range over 2 arrays, no 3rd array is created
.sort // sort in-place (again, no new array)
.uniq // lazy range of unique elements of chained array
.each!( (uniqComp) { // note uniqComp's type is inferred
auto verInfo = ["_name": uniqComp];
[srv1, srv2]
.enumerate
.each!( serv =>
["ver", "rev"].each!( prop =>
verInfo[prop ~ serv.index.to!string] = serv.value.get(uniqComp, ["": ""]).get(prop, ""))
);
/+ // The same as above and I like this better, actually
foreach(servIdx, serv; [srv1, srv2].enumerate){
foreach(prop; ["ver", "rev"])
verInfo[prop ~ servIdx.to!string] = serv.get(uniqComp, ["": ""]).get(prop, "");
} +/
result ~= verInfo;
});
writeln("---");
writeln(JSONValue(result).toPrettyString());
writeln("---");
}