mapexcept iterate

This commit is contained in:
John Kerl 2017-04-16 17:37:00 -04:00
parent 59fb7cca40
commit 07924fcf85
4 changed files with 50 additions and 7 deletions

View file

@ -158,6 +158,46 @@ boxed_xval_t variadic_mapdiff_xfunc(boxed_xval_t* pbxvals, int nxvals) {
return box_ephemeral_xval(diff);
}
// ----------------------------------------------------------------
boxed_xval_t variadic_mapexcept_xfunc(
boxed_xval_t* pbxvals,
int nxvals)
{
mlhmmv_xvalue_t except = mlhmmv_xvalue_alloc_empty_map();
if (nxvals == 0) {
return box_ephemeral_xval(except);
}
// xxx to-do optmization: transfer arg 1 if it's ephemeral
// xxx methodize
int i = 0;
if (!pbxvals[i].xval.is_terminal) {
mlhmmv_level_t* plevel = pbxvals[i].xval.pnext_level;
for (mlhmmv_level_entry_t* pe = plevel->phead; pe != NULL; pe = pe->pnext) {
// xxx do refs/copies correctly
mlhmmv_xvalue_t xval_copy = mlhmmv_xvalue_copy(&pe->level_xvalue);
sllmve_t e = (sllmve_t) { .value = pe->level_key, .free_flags = 0, .pnext = NULL };
mlhmmv_level_put_xvalue(except.pnext_level, &e, &xval_copy);
}
if (pbxvals[i].is_ephemeral)
mlhmmv_xvalue_free(&pbxvals[i].xval);
}
for (i = 1; i < nxvals; i++) {
if (!pbxvals[i].xval.is_terminal) {
mlhmmv_level_t* plevel = pbxvals[i].xval.pnext_level;
for (mlhmmv_level_entry_t* pe = plevel->phead; pe != NULL; pe = pe->pnext) {
sllmve_t e = (sllmve_t) { .value = pe->level_key, .free_flags = 0, .pnext = NULL };
mlhmmv_level_remove(except.pnext_level, &e);
}
}
if (pbxvals[i].is_ephemeral)
mlhmmv_xvalue_free(&pbxvals[i].xval);
}
return box_ephemeral_xval(except);
}
// ----------------------------------------------------------------
// Precondition: the caller has ensured that both arguments are string-valued terminals.
boxed_xval_t m_ss_splitnv_xfunc(boxed_xval_t* pstringval, boxed_xval_t* psepval) {

View file

@ -312,6 +312,9 @@ boxed_xval_t variadic_mapsum_xfunc(
boxed_xval_t variadic_mapdiff_xfunc(
boxed_xval_t* pbxvals, int nxvals);
boxed_xval_t variadic_mapexcept_xfunc(
boxed_xval_t* pbxvals, int nxvals);
boxed_xval_t m_ss_splitnv_xfunc(
boxed_xval_t* pstringval,
boxed_xval_t* psepval);

View file

@ -391,8 +391,10 @@ static function_lookup_t FUNCTION_LOOKUP_TABLE[] = {
{FUNC_CLASS_MAPS, "length", 1,0, "Counts number of top-level entries in hashmap. Scalars have length 1."},
{FUNC_CLASS_MAPS, "mapdiff", 0,1, "With 0 args, returns empty map. With 1 arg, returns copy of arg.\n"
"With 2 or more, returns copy of arg 1 with all keys from any of remaining argument maps removed."},
{FUNC_CLASS_MAPS, "mapexcept", 0,1, "With 1 args, returns argument map. With >= 2 args, returns a map with\n"
"keys from remaining arguments unset. E.g. 'mapexcept({1:2,3:4,5:6}, 1, 5, 7)' is '{3:4}'."},
{FUNC_CLASS_MAPS, "mapsum", 0,1, "With 0 args, returns empty map. With >= 1 arg, returns a map with\n"
"key-value pairs from all arguments. Rightmost collisions win, e.g. 'mapsum({1:2,3,4},{1:5})' is '{1:5,3:4}'."},
"key-value pairs from all arguments. Rightmost collisions win, e.g. 'mapsum({1:2,3:4},{1:5})' is '{1:5,3:4}'."},
{FUNC_CLASS_MAPS, "splitkv", 3,0, "Splits string by separators into map with type inference.\n"
"E.g. 'splitkv(\"a=1,b=2,c=3\", \"=\", \",\")' gives '{\"a\" : 1, \"b\" : 2, \"c\" : 3}'."},
{FUNC_CLASS_MAPS, "splitkvx", 3,0, "Splits string by separators into map without type inference (keys and\n"
@ -1280,6 +1282,9 @@ static rxval_evaluator_t* fmgr_alloc_xevaluator_from_variadic_func_name(
} else if (streq(function_name, "mapdiff")) {
return rxval_evaluator_alloc_from_variadic_func(variadic_mapdiff_xfunc, parg_nodes,
pfmgr, type_inferencing, context_flags);
} else if (streq(function_name, "mapexcept")) {
return rxval_evaluator_alloc_from_variadic_func(variadic_mapexcept_xfunc, parg_nodes,
pfmgr, type_inferencing, context_flags);
} else {
return NULL;
}

7
c/oo
View file

@ -39,9 +39,4 @@ vee=
# ----------------------------------------------------------------
announce
run_mlr cat $indir/joina.dkvp
run_mlr cat $indir/joinb.dkvp
run_mlr join -l l -r r -j j -f $indir/joina.dkvp $indir/joinb.dkvp
run_mlr join -l l -j r -f $indir/joina.dkvp $indir/joinb.dkvp
run_mlr join -r r -j l -f $indir/joina.dkvp $indir/joinb.dkvp
run_mlr --from $indir/abixy put 'dump mapexcept($*, "a")'