]> granicus.if.org Git - jq/commitdiff
fix sub (#586); add gsub/3; add transpose/0.
authorpkoppstein <pkoppstein@gmail.com>
Mon, 6 Oct 2014 18:37:57 +0000 (14:37 -0400)
committerWilliam Langford <wlangfor@gmail.com>
Tue, 7 Oct 2014 01:32:07 +0000 (21:32 -0400)
Signed-off-by: William Langford <wlangfor@gmail.com>
builtin.c
docs/content/3.manual/manual.yml
tests/all.test

index 6f6689427688f18a8f1d4dff405f27714ea03774..7ca0f8174f1744fc8ab95bd5b3470b0ce0fe8b1d 100644 (file)
--- a/builtin.c
+++ b/builtin.c
@@ -1051,17 +1051,19 @@ static const char* const jq_builtins[] = {
   "def sub($re; s):"
   "  . as $in"
   "  | [match($re)]"
-  "  | .[0]"
-  "  | . as $r"
-     //  # create the \"capture\" object:
-  "  | reduce ( $r | .captures | .[] | select(.name != null) | { (.name) : .string } ) as $pair"
-  "      ({}; . + $pair)"
-  "  | if . == {} then $in | .[0:$r.offset]+s+.[$r.offset+$r.length:]"
-  "    else (. | s)"
+  "  | if length == 0 then $in"
+  "    else .[0]"
+  "    | . as $r"
+       //  # create the \"capture\" object:
+  "    | reduce ( $r | .captures | .[] | select(.name != null) | { (.name) : .string } ) as $pair"
+  "        ({}; . + $pair)"
+  "    | if . == {} then $in | .[0:$r.offset]+s+.[$r.offset+$r.length:]"
+  "      else (. | s)"
+  "      end"
   "    end ;",
   //
   // repeated substitution of re (which may contain named captures)
-  "def gsub($re; s):"
+  "def gsub($re; s; flags):"
   //   # _stredit(edits;s) - s is the \"to\" string, which might contain capture variables,
   //   # so if an edit contains captures, then create the capture object and pipe it to s
   "   def _stredit(edits; s):"
@@ -1076,7 +1078,8 @@ static const char* const jq_builtins[] = {
   "         else (if $l == 0 then \"\" else ($in | _stredit(edits[0:$l]; s)) end) + (. | s)"
   "         end"
   "     end ;"
-  "  [match($re;\"g\")] as $edits | _stredit($edits; s) ;",
+  "  [match($re; flags + \"g\")] as $edits | _stredit($edits; s) ;",
+  "def gsub($re; s): gsub($re; s; \"\");"
 
   //#######################################################################
   // range/3, with a `by` expression argument
@@ -1096,6 +1099,16 @@ static const char* const jq_builtins[] = {
   "def first: .[0];",
   "def last: .[-1];",
   "def nth($n): .[$n];",
+  // # transpose a possibly jagged matrix, quickly; 
+  // # rows are padded with nulls so the result is always rectangular.
+  "def transpose:"
+  "  if . == [] then []"
+  "  else . as $in"
+  "  | (map(length) | max) as $max"
+  "  | length as $length"
+  "  | reduce range(0; $max) as $j"
+  "      ([]; . + [reduce range(0;$length) as $i ([]; . + [ $in[$i][$j] ] )] )"
+             "  end;",
 };
 #undef LIBM_DD
 
index 16bee1eb8f17bd9939c78289d78b933a867d0442..a89feb678b34b5fc96e2cb3344f26807ea227fe7 100644 (file)
@@ -1341,6 +1341,18 @@ sections:
             input: 'null'
             output: ['"less"']
 
+      - title: "`transpose`"
+        body: |
+
+          Transpose a possibly jagged matrix (an array of arrays). 
+          Rows are padded with nulls so the result is always rectangular.
+
+        examples:
+          - program: 'target'
+            input: '[[1], [2,3]]'
+            output: ['[1,2],[null,3]']
+
+
       - title: "String interpolation - `\\(foo)`"
         body: |
 
index 180789093d32042024f3c8c0ccb412c50be69777..84d4491d4e13a0bef27611e020dee2ea0bc0f2df 100644 (file)
@@ -1094,3 +1094,7 @@ flatten(2)
 flatten(2)
 [0, [1, [2]], [1, [[3], 2]]]
 [0, 1, 2, 1, [3], 2]
+
+transpose
+[[1], [2,3]]
+[[1,2],[null,3]]