I would really love it if we could subscript a list with a matrix and have it shape the list into a list of lists.
l = {"A", "B", "C", "D", "E", "F"}; ss = [1 2, 3 4, 5 6]; l[ss]; // I want this to come out as {{"A", "B"}, {"C", "D"}, {"E", "F"}};
@vince_faller ,
I have a slightly more generic wish. But decided to pile on. It is a repeat wish for a function that evaluates each item in a list, much like a function is appleid to each element in a matrix.
If available, then
l[ AsList( ss ) ] would return the desired result.
I use LFunc() often. I wish it were a built in capability. A script is attached with my version of a function. Remove /* at line 81 to
l = {"A", "B", "C", "D", "E", "F"}; ss = [1 2, 1 4, 5 2]; ssl = As List(ss); rst = Lfunc(ssl,Expr(l[x])); show(l, ssl,rst);
Log output
/*: ssl = {{1, 2}, {1, 4}, {5, 2}}; rst = {{"A", "B"}, {"A", "D"}, {"E", "B"}};
In case someone on the blog might be interested.
Lfunc = Function( {xList, fExpr/*ex. Expr(Contains(x,"h"))*/}, {x = {}, i = 1, errCode = 0, errStr = "\!NError bad argument", newExpr}, If( !Is List( xList ), errCode = 1 ); If( Type( Name Expr( fExpr ) ) == "Name", //if Name then JMP does not recognize the function tmp = Trim( Char( Name Expr( fExpr ) ) ); //extract the function and check if it is contained in the global namespace, if not error! If( Namespace( "global" ) << Contains( Word( 1, tmp, ":(" ) ) == 0, errCode = errCode + 2 );, Type( Name Expr( fExpr ) ) != "Expression", errCode = errCode + 2 ); //catches typos, returns Name if not a valid function //catches typos, returns Name if not a valid function If( !Is Expr( Name Expr( fExpr ) ), errCode = errCode + 2 ); //catches syntax If( !errCode, For( i = 1, i <= N Items( xList ), i++, newExpr = Substitute( Name Expr( fExpr ), Expr( x ), xList[i] ); insert Into(x, ""); x[i] = Eval(Expr(Try( newExpr, Empty() ))); ), errCode == 1, Write( errStr || "(1) not a list \!N" ), errCode == 2, Write( errStr || "(2) not a valid expression \!N" ), errCode == 3, Write( errStr || "s (1) is not a list and (2) is not a valid expression \!N" ) ); x//return x ; ); //End Lfunc l = {"A", "B", "C", "D", "E", "F"}; ss = [1 2, 1 4, 5 2]; ssl = As List(ss); rst = Lfunc(ssl,Expr(l[x])); show(l, ssl,rst); Lfunc = Function( {xList, fExpr/*ex. Expr(Contains(x,"h"))*/}, {x = {}, i = 1, errCode = 0, errStr = "\!NError bad argument", newExpr}, If( !Is List( xList ), errCode = 1 ); If( Type( Name Expr( fExpr ) ) == "Name", //if Name then JMP does not recognize the function tmp = Trim( Char( Name Expr( fExpr ) ) ); //extract the function and check if it is contained in the global namespace, if not error! If( Namespace( "global" ) << Contains( Word( 1, tmp, ":(" ) ) == 0, errCode = errCode + 2 );, Type( Name Expr( fExpr ) ) != "Expression", errCode = errCode + 2 ); //catches typos, returns Name if not a valid function //catches typos, returns Name if not a valid function If( !Is Expr( Name Expr( fExpr ) ), errCode = errCode + 2 ); //catches syntax If( !errCode, For( i = 1, i <= N Items( xList ), i++, newExpr = Substitute( Name Expr( fExpr ), Expr( x ), xList[i] ); insert Into(x, ""); x[i] = Eval(Expr(Try( newExpr, Empty() ))); ), errCode == 1, Write( errStr || "(1) not a list \!N" ), errCode == 2, Write( errStr || "(2) not a valid expression \!N" ), errCode == 3, Write( errStr || "s (1) is not a list and (2) is not a valid expression \!N" ) ); x//return x ; ); //End Lfunc /* //Usage & Test ...remove the slash asterisk and run in segments, results are in the log //------------------------------------------------------------------------------ myList={"john", "harry", "huh","ah ha", "xyx", , "a", "h", 7, [1,7]}; /* returns a list of numeric values, one value for each item in the list // n =>1st location of h, 0 => does not contain, Empty() => the item is not // a valid argument for that expression. // */ zz = Lfunc(myList,Expr(Contains(x,"h"))); myList={"john", "harry", "huh","ah ha", "xyx", , "a", "h"}; zz=Lfunc(myList, Expr(Uppercase(x))); show(zz); ----------------------------------------------------------------------------------------- /* returns a list of how many words are in each string [] -> no occurrences Empty() => the expression is not valid for that item. */ zz = Lfunc(mylist, expr(nitems(words(x)))); show(zz); ----------------------------------------------------------------------------------------- /* This specified function requires numeric arguments Empty() => the expression is not valid for that item. A numeric function applied to a matrix returns a matrix of the results applied on each element in the matrix. Only the last 2 items are valid arguments for Log() */ myList={"john", "harry", "huh","ah ha", "xyx", , "a", "h", 7, [1,7]}; zz = Lfunc(mylist, expr(log(x))); show(zz); ----------------Error Checking--------------------------------------------------------------- zz = Lfunc("oh johhny", Expr(Contains(x,"h")) ); //not a list show(zz); zz = Lfunc({"oh johhny"}, Expr(Contians(x,"h")) ); //type not a valid expr due to typo show(zz); zz = Lfunc("oh johhny", Expr(Contians(x,"h")) ); //not a list and not a valid expr show(zz); ----- end test */
Good idea on the 2D subscripting, but since there is already a behavior for that, it doesn't seem worth breaking any scripts expecting the current behavior. Best alternative that comes to mind is to make it easier to reshape the current output to match in index shape. Something like: shape(l[ss], ss)