forked from extern/nushell
Flexible dropping of rows (by desired row number) (#3917)
We very well support `nth 0 2 3 --skip 1 4` to select particular rows and skip some using a flag. However, in practice we deal with tables (whether they come from parsing or loading files and whatnot) where we don't know the size of the table up front (and everytime we have these, they may have different sizes). There are also other use cases when we use intermediate tables during processing and wish to always drop certain rows and **keep the rest**. Usage: ``` ... | drop nth 0 ... | drop nth 3 8 ```
This commit is contained in:
parent
1bd3fdd912
commit
463dd48180
@ -1,5 +1,7 @@
|
||||
mod column;
|
||||
mod command;
|
||||
mod nth;
|
||||
|
||||
pub use column::SubCommand as DropColumn;
|
||||
pub use command::Command as Drop;
|
||||
pub use nth::SubCommand as DropNth;
|
||||
|
91
crates/nu-command/src/commands/filters/drop/nth.rs
Normal file
91
crates/nu-command/src/commands/filters/drop/nth.rs
Normal file
@ -0,0 +1,91 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_source::Tagged;
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
fn name(&self) -> &str {
|
||||
"drop nth"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("drop nth")
|
||||
.required(
|
||||
"row number",
|
||||
SyntaxShape::Int,
|
||||
"the number of the row to drop",
|
||||
)
|
||||
.rest(SyntaxShape::Any, "Optionally drop more rows")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Drops the selected rows."
|
||||
}
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
drop(args)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Drop the second row",
|
||||
example: "echo [first second third] | drop nth 1",
|
||||
result: Some(vec![Value::from("first"), Value::from("third")]),
|
||||
},
|
||||
Example {
|
||||
description: "Drop the first and third rows",
|
||||
example: "echo [first second third] | drop nth 0 2",
|
||||
result: Some(vec![Value::from("second")]),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let row_number: Tagged<u64> = args.req(0)?;
|
||||
let and_rows: Vec<Tagged<u64>> = args.rest(1)?;
|
||||
let input = args.input;
|
||||
|
||||
let mut rows: Vec<_> = and_rows.into_iter().map(|x| x.item as usize).collect();
|
||||
rows.push(row_number.item as usize);
|
||||
rows.sort_unstable();
|
||||
|
||||
Ok(DropNthIterator {
|
||||
input,
|
||||
rows,
|
||||
current: 0,
|
||||
}
|
||||
.into_output_stream())
|
||||
}
|
||||
|
||||
struct DropNthIterator {
|
||||
input: InputStream,
|
||||
rows: Vec<usize>,
|
||||
current: usize,
|
||||
}
|
||||
|
||||
impl Iterator for DropNthIterator {
|
||||
type Item = Value;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
if let Some(row) = self.rows.get(0) {
|
||||
if self.current == *row {
|
||||
self.rows.remove(0);
|
||||
self.current += 1;
|
||||
let _ = self.input.next();
|
||||
continue;
|
||||
} else {
|
||||
self.current += 1;
|
||||
return self.input.next();
|
||||
}
|
||||
} else {
|
||||
return self.input.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -112,16 +112,3 @@ impl Iterator for NthIterator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Nth;
|
||||
use super::ShellError;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(Nth {})
|
||||
}
|
||||
}
|
||||
|
@ -65,12 +65,16 @@ mod tests {
|
||||
|
||||
fn full_tests() -> Vec<Command> {
|
||||
vec![
|
||||
whole_stream_command(Drop),
|
||||
whole_stream_command(DropNth),
|
||||
whole_stream_command(DropColumn),
|
||||
whole_stream_command(Append),
|
||||
whole_stream_command(GroupBy),
|
||||
whole_stream_command(Insert),
|
||||
whole_stream_command(MoveColumn),
|
||||
whole_stream_command(Update),
|
||||
whole_stream_command(Empty),
|
||||
whole_stream_command(Nth),
|
||||
// whole_stream_command(Select),
|
||||
// whole_stream_command(Get),
|
||||
// Str Command Suite
|
||||
|
@ -150,6 +150,7 @@ pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Bo
|
||||
whole_stream_command(Every),
|
||||
whole_stream_command(Nth),
|
||||
whole_stream_command(Drop),
|
||||
whole_stream_command(DropNth),
|
||||
whole_stream_command(Format),
|
||||
whole_stream_command(FileSize),
|
||||
whole_stream_command(Where),
|
||||
|
Loading…
Reference in New Issue
Block a user