Skip to content

Commit

Permalink
Add zip function and relevant documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
cube2222 committed Jan 9, 2022
1 parent e56b0b7 commit 7e01fcc
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 7 deletions.
8 changes: 1 addition & 7 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Make sure to check the documentation at http://goreleaser.com
before:
hooks:
# you may remove this if you don't use vgo
- go mod tidy
builds:
- binary: jql
Expand All @@ -12,14 +11,9 @@ builds:
- windows
goarch:
- amd64
- arm64
env:
- CGO_ENABLED=0
archives:
- replacements:
darwin: Darwin
linux: Linux
windows: Windows
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
Expand Down
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,34 @@ You can also use _object_ to create objects, with arguments alternating keys and
}
```

#### zip

Occasionally you might want to combine multiple arrays, you can use _zip_ to do that. For example, to create a list of key-value entries from an object, you can do the following:
```
> cat test.json | jql '("countries"
(0 (zip
(keys)
((keys)))))'
[
[
"eu_since",
"2004"
],
[
"european",
true
],
[
"name",
"Poland"
],
[
"population",
38000000
]
]
```

Now we're done with the **core** functionality of jql. The stuff so far will probably suffice for most use cases and even very complex data structures.

However, here come more functions:
Expand Down Expand Up @@ -515,6 +543,7 @@ eq,lt,gt: (Expression x Expression) -> (Expression[Bool])
range:
With one arg: (Expression[Int]) -> (Expression[Array[Int]])
With two args: (Expression[Int] x Expression[Int]) -> (Expression[Array[Int]])
zip: (Expression[Array[A]], Expression[Array[B]], ...) -> (Expression[Array[Array[A | B | ...]]])
and,or: (Expression[Bool]...) -> (Expression[Bool])
not: (Expression[Bool]) -> (Expression[Bool])
ifte: (Expression[Bool] x Expression[A] x Expression[B]) -> (Expression[A|B])
Expand Down
42 changes: 42 additions & 0 deletions jql/functions/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"reflect"
"runtime/debug"
"sort"
"strings"

"github.com/cube2222/jql/jql"
Expand All @@ -29,6 +30,7 @@ var Functions = map[string]func(ts ...jql.Expression) (jql.Expression, error){
"ifte": NewIfTE,
"error": NewError,
"recover": NewRecover,
"zip": NewZip,
}

type Element struct {
Expand Down Expand Up @@ -152,6 +154,9 @@ func (s Keys) Get(arg interface{}) (interface{}, error) {
for field := range typed {
outFields = append(outFields, field)
}
sort.Slice(outFields, func(i, j int) bool {
return outFields[i].(string) < outFields[j].(string)
})

return outFields, nil

Expand Down Expand Up @@ -738,3 +743,40 @@ func (t Recover) Get(arg interface{}) (out interface{}, err error) {

return value, nil
}

type Zip struct {
Arguments []jql.Expression
}

func NewZip(ts ...jql.Expression) (jql.Expression, error) {
return Zip{Arguments: ts}, nil
}

func (t Zip) Get(arg interface{}) (interface{}, error) {
args := make([][]interface{}, len(t.Arguments))
for i, curArg := range t.Arguments {
curArgValue, err := curArg.Get(arg)
if err != nil {
return nil, fmt.Errorf("couldn't evaluate argument with index %d: %w", i, err)
}

curArgValueTyped, ok := curArgValue.([]interface{})
if !ok {
return nil, fmt.Errorf("zip expects arrays as arguments, received %v of type %s", curArgValue, reflect.TypeOf(curArgValue))
}
args[i] = curArgValueTyped
}

var out []interface{}

for i := 0; ; i++ {
curOut := make([]interface{}, len(args))
for j := range args {
if i >= len(args[j]) {
return out, nil
}
curOut[j] = args[j][i]
}
out = append(out, curOut)
}
}

0 comments on commit 7e01fcc

Please sign in to comment.