forked from nushell/nu_scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
refine.nu
61 lines (56 loc) · 1.33 KB
/
refine.nu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
def safe_get [path obj] {
mut r = $obj
mut ps = $path
loop {
if ($ps | length) < 1 { break }
if $r == null { break }
let p = $ps | first
if ($p | describe -d).type == closure {
$r = ($r | do $p $r)
$ps = ($ps | range 1..)
continue
}
match ($r | describe -d).type {
record => {
if $p in $r {
$r = ($r | get $p)
} else {
$r = null
}
}
list => {
let ps = $ps
return ($r | each {|x| safe_get $ps $x })
}
_ => {
$r = null
}
}
$ps = ($ps | range 1..)
}
$r
}
def extract [tg obj] {
$tg
| transpose k v
| reduce -f {} {|i,a|
match ($i.v | describe -d).type {
list => {
let c = safe_get $i.v $obj
$a | upsert $i.k $c
}
record => {
let o = safe_get $i.v._ $obj
let t = $i.v | reject _
$a | upsert $i.k (main $t $o)
}
}
}
}
export def main [tg obj] {
if ($obj | describe -d).type == list {
$obj | each {|x| extract $tg $x }
} else {
extract $tg $obj
}
}