forked from extern/nushell
allow compact
to also compact empty strings (#10912)
# Description This change allows `compact` to also compact things with empty strings, empty lists, and empty records if the `--empty` switch is used. Let's add a quality-of-life improvement here to just compact all this mess. If this is a bad idea, please cite examples demonstrating why. ``` ❯ [[name position]; [Francis Lead] [Igor TechLead] [Aya null]] | compact position ╭#┬─name──┬position╮ │0│Francis│Lead │ │1│Igor │TechLead│ ╰─┴───────┴────────╯ ❯ [[name position]; [Francis Lead] [Igor TechLead] [Aya ""]] | compact position --empty ╭#┬─name──┬position╮ │0│Francis│Lead │ │1│Igor │TechLead│ ╰─┴───────┴────────╯ ❯ [1, null, 2, "", 3, [], 4, {}, 5] | compact ╭─┬─────────────────╮ │0│ 1│ │1│ 2│ │2│ │ │3│ 3│ │4│[list 0 items] │ │5│ 4│ │6│{record 0 fields}│ │7│ 5│ ╰─┴─────────────────╯ ❯ [1, null, 2, "", 3, [], 4, {}, 5] | compact --empty ╭─┬─╮ │0│1│ │1│2│ │2│3│ │3│4│ │4│5│ ╰─┴─╯ ``` # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
parent
15c22db8f4
commit
c1ca10ffd1
@ -27,6 +27,11 @@ impl Command for Compact {
|
||||
Type::List(Box::new(Type::Any)),
|
||||
),
|
||||
])
|
||||
.switch(
|
||||
"empty",
|
||||
"also compact empty items like \"\", {}, and []",
|
||||
Some('e'),
|
||||
)
|
||||
.rest(
|
||||
"columns",
|
||||
SyntaxShape::Any,
|
||||
@ -46,18 +51,19 @@ impl Command for Compact {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
compact(engine_state, stack, call, input)
|
||||
let empty = call.has_flag("empty");
|
||||
compact(engine_state, stack, call, input, empty)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Filter out all records where 'Hello' is null (returns nothing)",
|
||||
description: "Filter out all records where 'Hello' is null",
|
||||
example: r#"[["Hello" "World"]; [null 3]] | compact Hello"#,
|
||||
result: Some(Value::test_list(vec![])),
|
||||
},
|
||||
Example {
|
||||
description: "Filter out all records where 'World' is null (Returns the table)",
|
||||
description: "Filter out all records where 'World' is null",
|
||||
example: r#"[["Hello" "World"]; [null 3]] | compact World"#,
|
||||
result: Some(Value::test_list(vec![Value::test_record(record! {
|
||||
"Hello" => Value::nothing(Span::test_data()),
|
||||
@ -65,13 +71,24 @@ impl Command for Compact {
|
||||
})])),
|
||||
},
|
||||
Example {
|
||||
description: "Filter out all instances of nothing from a list (Returns [1,2])",
|
||||
description: "Filter out all instances of null from a list",
|
||||
example: r#"[1, null, 2] | compact"#,
|
||||
result: Some(Value::test_list(vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
])),
|
||||
},
|
||||
Example {
|
||||
description: "Filter out all instances of null and empty items from a list",
|
||||
example: r#"[1, null, 2, "", 3, [], 4, {}, 5] | compact --empty"#,
|
||||
result: Some(Value::test_list(vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(3),
|
||||
Value::test_int(4),
|
||||
Value::test_int(5),
|
||||
])),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -81,6 +98,7 @@ pub fn compact(
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
compact_empties: bool,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let columns: Vec<String> = call.rest(engine_state, stack, 0)?;
|
||||
let metadata = input.metadata();
|
||||
@ -90,7 +108,7 @@ pub fn compact(
|
||||
match item {
|
||||
// Nothing is filtered out
|
||||
Value::Nothing { .. } => false,
|
||||
Value::Record { .. } => {
|
||||
Value::Record { val, .. } => {
|
||||
for column in columns.iter() {
|
||||
match item.get_data_by_key(column) {
|
||||
None => return false,
|
||||
@ -98,12 +116,35 @@ pub fn compact(
|
||||
if let Value::Nothing { .. } = x {
|
||||
return false;
|
||||
}
|
||||
if compact_empties {
|
||||
if let Value::String { val, .. } = x {
|
||||
if val.is_empty() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if compact_empties && val.is_empty() {
|
||||
return false;
|
||||
}
|
||||
// No defined columns contained Nothing
|
||||
true
|
||||
}
|
||||
Value::List { vals, .. } => {
|
||||
if compact_empties && vals.is_empty() {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
Value::String { val, .. } => {
|
||||
if compact_empties && val.is_empty() {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
// Any non-Nothing, non-record should be kept
|
||||
_ => true,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user