Skip to content

Commit

Permalink
add merge function
Browse files Browse the repository at this point in the history
It does the same thing as `dict1 + dict2`, but takes any number of
dicts, or a list of dicts.

I think this is more readable than the `+` operator.
  • Loading branch information
christianp committed Dec 4, 2024
1 parent 0eb739b commit d07f741
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 24 deletions.
27 changes: 19 additions & 8 deletions runtime/scripts/jme-builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,29 @@ newBuiltin('+',[TList,'?'],TList, null, {
return new TList(value);
}
});
newBuiltin('+',[TDict,TDict],TDict, null,{

const fn_dict_update = {
evaluate: function(args,scope) {
var nvalue = {};
Object.keys(args[0].value).forEach(function(x) {
nvalue[x] = args[0].value[x];
})
Object.keys(args[1].value).forEach(function(x) {
nvalue[x] = args[1].value[x];
})

if(args.length == 1 && args[0].type == 'list') {
args = args[0].value;
}

args.forEach(arg => {
Object.keys(arg.value).forEach(function(x) {
nvalue[x] = arg.value[x];
});
});

return new TDict(nvalue);
}
});
}
newBuiltin('+',[TDict,TDict],TDict, null, fn_dict_update);

newBuiltin('merge',['*dict'],TDict, null, fn_dict_update);
newBuiltin('merge',['list of dict'],TDict, null, fn_dict_update);

var fconc = function(a,b) { return a+b; }
newBuiltin('+', [TString,'?'], TString, fconc);
newBuiltin('+', ['?',TString], TString, fconc);
Expand Down
27 changes: 19 additions & 8 deletions tests/jme-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -14301,18 +14301,29 @@ newBuiltin('+',[TList,'?'],TList, null, {
return new TList(value);
}
});
newBuiltin('+',[TDict,TDict],TDict, null,{

const fn_dict_update = {
evaluate: function(args,scope) {
var nvalue = {};
Object.keys(args[0].value).forEach(function(x) {
nvalue[x] = args[0].value[x];
})
Object.keys(args[1].value).forEach(function(x) {
nvalue[x] = args[1].value[x];
})

if(args.length == 1 && args[0].type == 'list') {
args = args[0].value;
}

args.forEach(arg => {
Object.keys(arg.value).forEach(function(x) {
nvalue[x] = arg.value[x];
});
});

return new TDict(nvalue);
}
});
}
newBuiltin('+',[TDict,TDict],TDict, null, fn_dict_update);

newBuiltin('merge',['*dict'],TDict, null, fn_dict_update);
newBuiltin('merge',['list of dict'],TDict, null, fn_dict_update);

var fconc = function(a,b) { return a+b; }
newBuiltin('+', [TString,'?'], TString, fconc);
newBuiltin('+', ['?',TString], TString, fconc);
Expand Down
34 changes: 34 additions & 0 deletions tests/jme/doc-tests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4592,6 +4592,40 @@ export default
"out": "[ [\"a\",1], [\"b\",2], [\"c\",1] ]"
}
]
},
{
"name": "merge",
"keywords": [
"dictionary",
"union",
"update"
],
"noexamples": false,
"calling_patterns": [
"merge(dict1, dict2, ..., dictN)"
],
"examples": [
{
"in": "merge([\"a\": 1, \"b\": 1], [\"b\": 2, \"c\": 2])",
"out": "[\"a\": 1, \"b\": 2, \"c\": 2]"
},
{
"in": "merge([\"a\": 1], [\"b\": 2], [\"c\": 3])",
"out": "[\"a\": 1, \"b\": 2, \"c\": 3]"
},
{
"in": "merge([ [\"a\": 1], [\"b\": 2] ])",
"out": "[\"a\": 1, \"b\": 2]"
},
{
"in": "merge()",
"out": "dict()"
},
{
"in": "merge([])",
"out": "dict()"
}
]
}
]
},
Expand Down
27 changes: 19 additions & 8 deletions tests/numbas-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -13892,18 +13892,29 @@ newBuiltin('+',[TList,'?'],TList, null, {
return new TList(value);
}
});
newBuiltin('+',[TDict,TDict],TDict, null,{

const fn_dict_update = {
evaluate: function(args,scope) {
var nvalue = {};
Object.keys(args[0].value).forEach(function(x) {
nvalue[x] = args[0].value[x];
})
Object.keys(args[1].value).forEach(function(x) {
nvalue[x] = args[1].value[x];
})

if(args.length == 1 && args[0].type == 'list') {
args = args[0].value;
}

args.forEach(arg => {
Object.keys(arg.value).forEach(function(x) {
nvalue[x] = arg.value[x];
});
});

return new TDict(nvalue);
}
});
}
newBuiltin('+',[TDict,TDict],TDict, null, fn_dict_update);

newBuiltin('merge',['*dict'],TDict, null, fn_dict_update);
newBuiltin('merge',['list of dict'],TDict, null, fn_dict_update);

var fconc = function(a,b) { return a+b; }
newBuiltin('+', [TString,'?'], TString, fconc);
newBuiltin('+', ['?',TString], TString, fconc);
Expand Down

0 comments on commit d07f741

Please sign in to comment.