Repository: jsonata-js/jsonata (js)

Issue:
$map skipping every other element
Hello,

I have these 2 transforms that i would expect to be equivalent but they produce different results. Im using this context.
```json
[
  "Felicia Saunders",
  "Jimmy Schultz",
  "Dolores Figueroa",
  "Craig Moreno",
  "Lindsey Hall",
  "Bonnie Russell",
  "Kristin Stewart",
  "Owen Reid",
  "Brenda Sherman",
  "Dwayne Baldwin"
]
```
The first transform is the one that seems to be buggy.
`
$map($, $match(?, /^(\w*\s\w*)/))
`
Results
```json
[
  [
    {
      "match": "Felicia Saunders",
      "index": 0,
      "groups": [
        "Felicia Saunders"
      ]
    }
  ],
  [],
  [
    {
      "match": "Dolores Figueroa",
      "index": 0,
      "groups": [
        "Dolores Figueroa"
      ]
    }
  ],
  [],
  [
    {
      "match": "Lindsey Hall",
      "index": 0,
      "groups": [
        "Lindsey Hall"
      ]
    }
  ],
  [],
  [
    {
      "match": "Kristin Stewart",
      "index": 0,
      "groups": [
        "Kristin Stewart"
      ]
    }
  ],
  [],
  [
    {
      "match": "Brenda Sherman",
      "index": 0,
      "groups": [
        "Brenda Sherman"
      ]
    }
  ],
  []
]
```
This produces what i would expect
`
$map($, function($i){
    $match($i, /^(\w*\s\w*)/)
})
`
Results
```json
[
  [
    {
      "match": "Felicia Saunders",
      "index": 0,
      "groups": [
        "Felicia Saunders"
      ]
    }
  ],
  [
    {
      "match": "Jimmy Schultz",
      "index": 0,
      "groups": [
        "Jimmy Schultz"
      ]
    }
  ],
  [
    {
      "match": "Dolores Figueroa",
      "index": 0,
      "groups": [
        "Dolores Figueroa"
      ]
    }
  ],
  [
    {
      "match": "Craig Moreno",
      "index": 0,
      "groups": [
        "Craig Moreno"
      ]
    }
  ],
  [
    {
      "match": "Lindsey Hall",
      "index": 0,
      "groups": [
        "Lindsey Hall"
      ]
    }
  ],
  [
    {
      "match": "Bonnie Russell",
      "index": 0,
      "groups": [
        "Bonnie Russell"
      ]
    }
  ],
  [
    {
      "match": "Kristin Stewart",
      "index": 0,
      "groups": [
        "Kristin Stewart"
      ]
    }
  ],
  [
    {
      "match": "Owen Reid",
      "index": 0,
      "groups": [
        "Owen Reid"
      ]
    }
  ],
  [
    {
      "match": "Brenda Sherman",
      "index": 0,
      "groups": [
        "Brenda Sherman"
      ]
    }
  ],
  [
    {
      "match": "Dwayne Baldwin",
      "index": 0,
      "groups": [
        "Dwayne Baldwin"
      ]
    }
  ]
]
```
Does this seem like a bug or is there something im missing?

Thanks

Pull request description:
Reset lastIndex on RegExp objects that get reused in closures
When partially applying the $match function, the regex was compiled and stored in the closure.
The same RegExp object was then applied multiple times in the $map, but the lastIndex property was not being reset, so alternate matches would fail (which then resets lastIndex to 0).

This PR fixes that.

resolves #427 

Signed-off-by: andrew-coleman <andrew_coleman@uk.ibm.com>

Patch:
diff --git a/src/jsonata.js b/src/jsonata.js
index d23cfe4..5924bac 100644
--- a/src/jsonata.js
+++ b/src/jsonata.js
@@ -1089,8 +1089,9 @@ var jsonata = (function() {
      */
     function evaluateRegex(expr) {
         var re = new RegExp(expr.value);
-        var closure = function(str) {
+        var closure = function(str, fromIndex) {
             var result;
+            re.lastIndex = fromIndex || 0;
             var match = re.exec(str);
             if(match !== null) {
                 result = {
@@ -1108,7 +1109,7 @@ var jsonata = (function() {
                     if(re.lastIndex >= str.length) {
                         return undefined;
                     } else {
-                        var next = closure(str);
+                        var next = closure(str, re.lastIndex);
                         if(next && next.match === '') {
                             // matches zero length string; this will never progress
                             throw {


Test patch:
diff --git a/test/test-suite/groups/regex/case037.json b/test/test-suite/groups/regex/case037.json
new file mode 100644
index 0000000..d9c5264
--- /dev/null
+++ b/test/test-suite/groups/regex/case037.json
@@ -0,0 +1,28 @@
+{
+    "expr": "$map($, $match(?, /^(\\w*\\s\\w*)/)).match",
+    "data": [
+        "Felicia Saunders",
+        "Jimmy Schultz",
+        "Dolores Figueroa",
+        "Craig Moreno",
+        "Lindsey Hall",
+        "Bonnie Russell",
+        "Kristin Stewart",
+        "Owen Reid",
+        "Brenda Sherman",
+        "Dwayne Baldwin"
+    ],
+    "bindings": {},
+    "result": [
+        "Felicia Saunders",
+        "Jimmy Schultz",
+        "Dolores Figueroa",
+        "Craig Moreno",
+        "Lindsey Hall",
+        "Bonnie Russell",
+        "Kristin Stewart",
+        "Owen Reid",
+        "Brenda Sherman",
+        "Dwayne Baldwin"
+    ]
+}
diff --git a/test/test-suite/groups/regex/case038.json b/test/test-suite/groups/regex/case038.json
new file mode 100644
index 0000000..0049fd6
--- /dev/null
+++ b/test/test-suite/groups/regex/case038.json
@@ -0,0 +1,28 @@
+{
+    "expr": "$map($, function($i){ $match($i, /^(\\w*\\s\\w*)/) }).match",
+    "data": [
+        "Felicia Saunders",
+        "Jimmy Schultz",
+        "Dolores Figueroa",
+        "Craig Moreno",
+        "Lindsey Hall",
+        "Bonnie Russell",
+        "Kristin Stewart",
+        "Owen Reid",
+        "Brenda Sherman",
+        "Dwayne Baldwin"
+    ],
+    "bindings": {},
+    "result": [
+        "Felicia Saunders",
+        "Jimmy Schultz",
+        "Dolores Figueroa",
+        "Craig Moreno",
+        "Lindsey Hall",
+        "Bonnie Russell",
+        "Kristin Stewart",
+        "Owen Reid",
+        "Brenda Sherman",
+        "Dwayne Baldwin"
+    ]
+}