Skip to content

Commit

Permalink
Add gray matter
Browse files Browse the repository at this point in the history
  • Loading branch information
nntrn committed Dec 14, 2023
1 parent 46207e8 commit 6975dad
Show file tree
Hide file tree
Showing 24 changed files with 270 additions and 21 deletions.
38 changes: 38 additions & 0 deletions data/unroll-example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"results": [
{
"id": 306,
"name": "First Company",
"branches": [
{
"id": 4191,
"city": "Seattle",
"customers": [
{
"id": 446,
"name": "Big Tech 1"
},
{
"id": 447,
"name": "Big Tech 2"
}
]
},
{
"id": 4192,
"city": "Oakland",
"customers": [
{
"id": 448,
"name": "Health Tech 1"
},
{
"id": 449,
"name": "Health Tech 2"
}
]
}
]
}
]
}
4 changes: 3 additions & 1 deletion functions/barcharts.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# barcharts
---
title: barcharts
---

```jq
def barchart($key):
Expand Down
4 changes: 3 additions & 1 deletion functions/conversion.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# conversion
---
title: conversion
---

Pretty print numbers

Expand Down
5 changes: 4 additions & 1 deletion functions/describe.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# describe
---
title: describe
data: data/sample-github-events.json
---

Get object outline

Expand Down
6 changes: 5 additions & 1 deletion functions/flatten.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Flatten
---
title: Flatten
data: data/sample-github-events.json
---


## Flat JSON

Expand Down
4 changes: 3 additions & 1 deletion functions/github-api.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# github api
---
title: github api
---

```jq
def github_raw_url:
Expand Down
4 changes: 3 additions & 1 deletion functions/json2csv.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# json2csv
---
title: json2csv
---

```jq
# ~/.jq/convert.jq
Expand Down
4 changes: 3 additions & 1 deletion functions/pick.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# pick
---
title: pick
---

[[Source]](https://github.com/jqlang/jq/issues/2578#issuecomment-1532632453)

Expand Down
4 changes: 3 additions & 1 deletion functions/read-history.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Read history
---
title: Read history
---

Compile timestamps in `.bash_history` for all users

Expand Down
4 changes: 3 additions & 1 deletion functions/summary.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# summary
---
title: summary
---

```jq
def grouped_summary($item):
Expand Down
94 changes: 94 additions & 0 deletions functions/unroll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: Unroll
source:
- https://stackoverflow.com/a/33290267
---


```jq
[leaf_paths as $path | {
"key": $path | map(tostring) | join("_"),
"value": getpath($path)
}] | from_entries
```

```console
$ cat data/nested.json|jq '[leaf_paths as $path | {
"key": $path | map(tostring) | join("_"),
"value": getpath($path)
}] | from_entries
'
{
"server_atx_user": "annie",
"server_atx_port": 22,
"storage_nyc_user": "nntrn",
"storage_nyc_port": 22
}
```



```jq
def categorize:
# Returns "object", "array" or "scalar" to indicate the category
# of the piped element.
if type == "object" then "object"
elif type == "array" then "array"
else "scalar"
end;
def pluck($category):
# Plucks the children of a particular category from piped element.
if categorize != "object"
then empty
else to_entries[]
| select(.value | categorize == $category)
| .value
end;
def split:
# Splits the piped element's children into arrays, scalars, and objects
# and returns a meta object containing the children seperated by these
# keys. If the piped element is a scalar or array, this does not look
# at the children, but just returns that element in the meta object.
if categorize == "scalar" then { objects: [], arrays: [], scalars: [.] }
elif categorize == "array" then { objects: [], arrays: [.], scalars: [] }
else { objects: [pluck("object")], arrays : [pluck("array")], scalars: [pluck("scalar")] }
end;
def unwrap:
# Unwraps an array recursively, until the elements of the returned array
# are either scalars or objects but not arrays. If piped element is not
# an array, returns the element as is.
if type != "array" then .
elif length == 0 then empty
else .[] | unwrap
end;
def extract($category):
# Extracts the elements of a particular category from the piped in array.
# If the piped in element is not an array, this fn acts as filter to
# only return the element if it is of the desired category.
unwrap | select(.| categorize == $category);
def unroll:
# Unrolls the passed in object recursively until only scalars are left.
# Returns a row for each leaf node of tree structure of the object and
# elements of the row would be all the scalars encountered at all the
# ancestor levels of this left node.
. | .result += .state.scalars
| .state.objects += [.state.arrays | extract("object")]
| .state.objects += [.state.arrays | extract("scalar")]
| if (.state.objects | length == 0 )
then .result
else ({ data : .state.objects,
state: .state.objects[] | split,
result: .result
} | unroll)
end;
def unrolls($data): { data: $data, state: $data| split, result: [] } | unroll ;
def unrolls: unrolls(.);
```
4 changes: 3 additions & 1 deletion general/codepoints.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Codepoints
---
title: Codepoints
---

Work with explode/implode

Expand Down
4 changes: 3 additions & 1 deletion general/data-cleaning.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Data cleaning
---
title: Data cleaning
---

## Delete keys

Expand Down
7 changes: 5 additions & 2 deletions data-transform.md → general/data-transform.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# Data transformation
---
title: Data transformation
data: data/nested.json
---

## json2ini

Adapted from <a>https://stackoverflow.com/a/76665197</a>

Data used: [nested.json](data/nested.json)
Data used: [nested.json](../data/nested.json)

```
{
Expand Down
4 changes: 3 additions & 1 deletion general/examples.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Examples
---
title: Examples
---

## Reduce

Expand Down
5 changes: 4 additions & 1 deletion general/inputs.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Working with `inputs`
---
title: Inputs
data: data/tmp.tsv
---

**DATA**: [tmp.tsv](../data/tmp.tsv)

Expand Down
4 changes: 3 additions & 1 deletion general/kv.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# kv
---
title: kv
---

```jq
split("\n")
Expand Down
4 changes: 3 additions & 1 deletion general/oneliners.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Oneliners
---
title: Oneliners
---

## Recursively convert appropriate data types from string

Expand Down
4 changes: 3 additions & 1 deletion general/reduce.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Reduce
---
title: Reduce
---

```jq
def tocsv:
Expand Down
4 changes: 3 additions & 1 deletion general/scalars.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Scalars
---
title: Scalars
---

Scalars are variables that hold an *individual* value (strings, integers, and booleans). If it's not an object or array &mdash; it's most likely a scalar

Expand Down
4 changes: 3 additions & 1 deletion general/streams.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Working with streams
---
title: Working with streams
---

Data used: [nested.json](../data/outer.json)

Expand Down
4 changes: 3 additions & 1 deletion general/wrangle.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Wrangle
---
title: Wrangle
---

## Zip Column Headers

Expand Down
10 changes: 10 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ git clone -b staging https://github.com/nntrn/jq-recipes.git
git clone https://github.com/nntrn/jq-recipes.wiki.git
```

## Setup

```sh
curl --create-dirs -o ~/.jq/recipes.jq https://nntrn.github.io/jq-recipes/recipes.jq

git clone -b staging https://github.com/nntrn/jq-recipes.git


```

[Github Page](http://nntrn.github.io/jq-recipes) | [Wiki](https://github.com/nntrn/jq-recipes/wiki)
62 changes: 62 additions & 0 deletions unroll.jq
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
def categorize:
# Returns "object", "array" or "scalar" to indicate the category
# of the piped element.
if type == "object" then "object"
elif type == "array" then "array"
else "scalar"
end;

def pluck($category):
# Plucks the children of a particular category from piped element.
if categorize != "object"
then empty
else to_entries[]
| select(.value | categorize == $category)
| .value
end;

def split:
# Splits the piped element's children into arrays, scalars, and objects
# and returns a meta object containing the children seperated by these
# keys. If the piped element is a scalar or array, this does not look
# at the children, but just returns that element in the meta object.
if categorize == "scalar" then { objects: [], arrays: [], scalars: [.] }
elif categorize == "array" then { objects: [], arrays: [.], scalars: [] }
else { objects: [pluck("object")], arrays : [pluck("array")], scalars: [pluck("scalar")] }
end;

def unwrap:
# Unwraps an array recursively, until the elements of the returned array
# are either scalars or objects but not arrays. If piped element is not
# an array, returns the element as is.

if type != "array" then .
elif length == 0 then empty
else .[] | unwrap
end;

def extract($category):
# Extracts the elements of a particular category from the piped in array.
# If the piped in element is not an array, this fn acts as filter to
# only return the element if it is of the desired category.
unwrap | select(.| categorize == $category);

def unroll:
# Unrolls the passed in object recursively until only scalars are left.
# Returns a row for each leaf node of tree structure of the object and
# elements of the row would be all the scalars encountered at all the
# ancestor levels of this left node.

. | .result += .state.scalars
| .state.objects += [.state.arrays | extract("object")]
| .state.objects += [.state.arrays | extract("scalar")]
| if (.state.objects | length == 0 )
then .result
else ({ data : .state.objects,
state: .state.objects[] | split,
result: .result
} | unroll)
end;

def unrolls($data): { data: $data, state: $data| split, result: [] } | unroll ;
def unrolls: unrolls(.);

0 comments on commit 6975dad

Please sign in to comment.