diff --git a/stdlib-candidate/std-rfc/conversions/columns-into-table.nu b/stdlib-candidate/std-rfc/conversions/columns-into-table.nu
new file mode 100644
index 0000000..380d180
--- /dev/null
+++ b/stdlib-candidate/std-rfc/conversions/columns-into-table.nu
@@ -0,0 +1,31 @@
+# Convert a list of columns into a table
+#
+# Examples:
+#
+# [
+# ([ 1 2 3 ] | wrap a)
+# ([ 4 5 6 ] | wrap b)
+# ([ 7 8 9 ] | wrap c)
+# ] | columns-into-table
+# => ╭───┬───┬───┬───╮
+# => │ # │ a │ b │ c │
+# => ├───┼───┼───┼───┤
+# => │ 0 │ 1 │ 4 │ 7 │
+# => │ 1 │ 2 │ 5 │ 8 │
+# => │ 2 │ 3 │ 6 │ 9 │
+# => ╰───┴───┴───┴───╯
+#
+# Can roundtrip with `table-into-columns`
+#
+# ls | table-into-columns | columns-into-table
+# => ╭───┬────────────────────────┬──────┬────────┬────────────────╮
+# => │ # │ name │ type │ size │ modified │
+# => ├───┼────────────────────────┼──────┼────────┼────────────────┤
+# => │ 0 │ into-list.nu │ file │ 378 B │ 40 minutes ago │
+# => │ 1 │ mod.nu │ file │ 28 B │ 41 minutes ago │
+# => │ 2 │ name-values.nu │ file │ 394 B │ 34 minutes ago │
+# => │ 3 │ record-into-columns.nu │ file │ 1.3 kB │ 27 minutes ago │
+# => ╰───┴────────────────────────┴──────┴────────┴────────────────╯
+export def main []: [list
-> table] {
+ reduce {|it| merge $it}
+}
diff --git a/stdlib-candidate/std-rfc/conversions/into.nu b/stdlib-candidate/std-rfc/conversions/into-list.nu
similarity index 79%
rename from stdlib-candidate/std-rfc/conversions/into.nu
rename to stdlib-candidate/std-rfc/conversions/into-list.nu
index fe859ca..6d65975 100644
--- a/stdlib-candidate/std-rfc/conversions/into.nu
+++ b/stdlib-candidate/std-rfc/conversions/into-list.nu
@@ -1,7 +1,6 @@
# Convert a Nushell value to a list
#
-# Primary useful for range-to-list,
-# but other types are accepted as well.
+# Primary useful for range-to-list, but other types are accepted as well.
#
# Example:
#
@@ -15,4 +14,4 @@ export def "into list" []: any -> list {
table => $input
_ => [ $input ]
}
-}
\ No newline at end of file
+}
diff --git a/stdlib-candidate/std-rfc/conversions/mod.nu b/stdlib-candidate/std-rfc/conversions/mod.nu
index fe7b611..066f0b0 100644
--- a/stdlib-candidate/std-rfc/conversions/mod.nu
+++ b/stdlib-candidate/std-rfc/conversions/mod.nu
@@ -1 +1,5 @@
-export use ./into.nu *
\ No newline at end of file
+export use ./into-list.nu *
+export use ./columns-into-table.nu *
+export use ./name-values.nu *
+export use ./record-into-columns.nu *
+export use ./table-into-columns.nu *
diff --git a/stdlib-candidate/std-rfc/conversions/name-values.nu b/stdlib-candidate/std-rfc/conversions/name-values.nu
new file mode 100644
index 0000000..d4c664e
--- /dev/null
+++ b/stdlib-candidate/std-rfc/conversions/name-values.nu
@@ -0,0 +1,14 @@
+# Assign keynames to a list of values, effectively converting the list to a record.
+#
+# Example:
+#
+# [ 1 2 3 ] | name-values a b c
+# => ╭───┬───╮
+# => │ a │ 1 │
+# => │ b │ 2 │
+# => │ c │ 3 │
+# => ╰───┴───╯
+export def main [...names: string]: [list -> record] {
+ let IN = $in
+ 0.. | zip $IN | into record | rename ...$names
+}
diff --git a/stdlib-candidate/std-rfc/conversions/record-into-columns.nu b/stdlib-candidate/std-rfc/conversions/record-into-columns.nu
new file mode 100644
index 0000000..4c6b3dd
--- /dev/null
+++ b/stdlib-candidate/std-rfc/conversions/record-into-columns.nu
@@ -0,0 +1,34 @@
+# Convert a record, where each value is a list, into a list of columns.
+# { a: [ 1 2 3 ], b: [ 4 5 6 ] } | record-into-columns
+# => ╭───┬───────────╮
+# => │ 0 │ ╭───┬───╮ │
+# => │ │ │ # │ a │ │
+# => │ │ ├───┼───┤ │
+# => │ │ │ 0 │ 1 │ │
+# => │ │ │ 1 │ 2 │ │
+# => │ │ │ 2 │ 3 │ │
+# => │ │ ╰───┴───╯ │
+# => │ 1 │ ╭───┬───╮ │
+# => │ │ │ # │ b │ │
+# => │ │ ├───┼───┤ │
+# => │ │ │ 0 │ 4 │ │
+# => │ │ │ 1 │ 5 │ │
+# => │ │ │ 2 │ 6 │ │
+# => │ │ ╰───┴───╯ │
+# => ╰───┴───────────╯
+# =>
+# This can be especially useful when combined with `columns-into-table`, as in:
+#
+# { a: [ 1 2 3 ], b: [ 4 5 6 ] } | record-into-columns
+# | columns-into-table
+# => ╭───┬───┬───╮
+# => │ # │ a │ b │
+# => ├───┼───┼───┤
+# => │ 0 │ 1 │ 4 │
+# => │ 1 │ 2 │ 5 │
+# => │ 2 │ 3 │ 6 │
+# => ╰───┴───┴───╯
+# =>
+export def main []: [record -> list] {
+ items {|key, val| $val | wrap $key}
+}
diff --git a/stdlib-candidate/std-rfc/conversions/table-into-columns.nu b/stdlib-candidate/std-rfc/conversions/table-into-columns.nu
new file mode 100644
index 0000000..d9b9394
--- /dev/null
+++ b/stdlib-candidate/std-rfc/conversions/table-into-columns.nu
@@ -0,0 +1,21 @@
+# Convert/split a table into a list of columns
+#
+# Examples:
+# ls | table-into-columns
+# => Returns a list of 4 tables, one for each of the `ls` columns
+#
+# Can be roundtripped with `columns-into-table`
+#
+# ls | table-into-columns | columns-into-table
+# => ╭───┬────────────────────────┬──────┬────────┬────────────────╮
+# => │ # │ name │ type │ size │ modified │
+# => ├───┼────────────────────────┼──────┼────────┼────────────────┤
+# => │ 0 │ into-list.nu │ file │ 378 B │ 40 minutes ago │
+# => │ 1 │ mod.nu │ file │ 28 B │ 41 minutes ago │
+# => │ 2 │ name-values.nu │ file │ 394 B │ 34 minutes ago │
+# => │ 3 │ record-into-columns.nu │ file │ 1.3 kB │ 27 minutes ago │
+# => ╰───┴────────────────────────┴──────┴────────┴────────────────╯
+export def main []: [table -> list] {
+ let IN = $in
+ $IN | columns | each {|col| $IN | select $col}
+}
diff --git a/stdlib-candidate/std-rfc/tables/col-indices.nu b/stdlib-candidate/std-rfc/tables/col-indices.nu
index 02f9d04..202d413 100644
--- a/stdlib-candidate/std-rfc/tables/col-indices.nu
+++ b/stdlib-candidate/std-rfc/tables/col-indices.nu
@@ -1,4 +1,4 @@
-use ../conversions/into.nu *
+use ../conversions/into-list.nu *
use ./select-ranges.nu *
export def main [ ...ranges ] {
@@ -12,4 +12,4 @@ export def main [ ...ranges ] {
$in | columns
| select ranges $indices
| get item
-}
\ No newline at end of file
+}
diff --git a/stdlib-candidate/std-rfc/tables/reject-ranges.nu b/stdlib-candidate/std-rfc/tables/reject-ranges.nu
index 802bc48..87fa45e 100644
--- a/stdlib-candidate/std-rfc/tables/reject-ranges.nu
+++ b/stdlib-candidate/std-rfc/tables/reject-ranges.nu
@@ -1,10 +1,8 @@
use ./row-indices.nu *
-# Rejects one or more rows while keeping
-# the original indices.
+# Rejects one or more rows while keeping the original indices.
#
-# Example - Rejects the first, fifth, and
-# sixth rows from the table:
+# Example - Rejects the first, fifth, and sixth rows from the table:
#
# ls / | reject ranges 0 4..5
export def "reject ranges" [ ...ranges ] {
diff --git a/stdlib-candidate/std-rfc/tables/row-indices.nu b/stdlib-candidate/std-rfc/tables/row-indices.nu
index c153d12..d8f3bf3 100644
--- a/stdlib-candidate/std-rfc/tables/row-indices.nu
+++ b/stdlib-candidate/std-rfc/tables/row-indices.nu
@@ -1,9 +1,6 @@
-use ../conversions/into.nu *
+use ../conversions/into-list.nu *
-# Return a list of indices
-# for the provided ranges or indices.
-# Primarily used as a helper for
-# "select ranges" et. al.
+# Return a list of indices for the provided ranges or indices. Primarily used as a helper for "select ranges" et. al.
#
# Example:
#
@@ -22,4 +19,4 @@ export def main [ ...ranges ] {
| reduce -f [] {|range,indices|
$indices ++ ($range | into list)
}
-}
\ No newline at end of file
+}
diff --git a/stdlib-candidate/std-rfc/tables/select-ranges.nu b/stdlib-candidate/std-rfc/tables/select-ranges.nu
index 967c79d..a3fe9f2 100644
--- a/stdlib-candidate/std-rfc/tables/select-ranges.nu
+++ b/stdlib-candidate/std-rfc/tables/select-ranges.nu
@@ -1,10 +1,8 @@
use ./row-indices.nu *
-# Selects one or more rows while keeping
-# the original indices.
+# Selects one or more rows while keeping the original indices.
#
-# Example - Selects the first, fifth, and
-# sixth rows from the table:
+# Example - Selects the first, fifth, and sixth rows from the table:
#
# ls / | select ranges 0 4..5
#
@@ -13,10 +11,8 @@ use ./row-indices.nu *
# ls / | select 5
#
# Example - Select the 4th row.
-# Note that the difference between this
-# and `select 3` is that the index (#)
-# column shows the *original* (pre-select)
-# position in the table.
+#
+# Note that the difference between this and `select 3` is that the index (#) column shows the *original* (pre-select) position in the table.
#
# ls | select ranges 3
export def "select ranges" [ ...ranges ] {
diff --git a/stdlib-candidate/tests/conversions.nu b/stdlib-candidate/tests/conversions.nu
index 003d28c..04124f4 100644
--- a/stdlib-candidate/tests/conversions.nu
+++ b/stdlib-candidate/tests/conversions.nu
@@ -46,3 +46,65 @@ def list-into-list [] {
)
}
+
+#[test]
+def table-into-columns--roundtrip [] {
+ assert equal (
+ ls
+ ) (
+ ls | table-into-columns | columns-into-table
+ )
+}
+
+const test_record_of_lists = {
+ a: [ 1 2 3 ]
+ b: [ 4 5 6 ]
+}
+
+#[test]
+def record-into-columns--simple [] {
+ let actual = (
+ $test_record_of_lists
+ | record-into-columns
+ | get 1.b.2
+ )
+
+ let expected = 6
+
+ assert equal $actual $expected
+}
+
+#[test]
+def table-into-columns--simple [] {
+ let actual = (
+ ls | table-into-columns | get 1 | columns | get 0
+ )
+ let expected = 'type'
+
+ assert equal $actual $expected
+}
+
+#[test]
+def name-values--simple [] {
+ let actual = (
+ [ 1 2 3 ] | name-values one two three
+ | get 'two'
+ )
+
+ let expected = 2
+
+ assert equal $actual $expected
+}
+
+#[test]
+def name-values--missing-keyname [] {
+ let actual = (
+ [ 1 2 3 ] | name-values one two
+ | columns
+ )
+
+ # Column/key names are strings, even those that came from the index ('2')
+ let expected = [ 'one' 'two' '2' ]
+
+ assert equal $actual $expected
+}