mirror of
https://github.com/nushell/nushell.git
synced 2025-07-13 12:56:22 +02:00
`drop` is used for removing the last row. Passing a number allows dropping N rows. Here we introduce the same logic for dropping columns instead. You can certainly remove columns by using `reject`, however, there could be cases where we are interested in removing columns from tables that contain, say, a big number of columns. Using `reject` becomes impractical, especially when you don't care about the column names that could either be known or not known when exploring tables. ``` > echo [[lib, extension]; [nu-core, rs] [rake, rb]] ─────────┬─────────── lib │ extension ─────────┼─────────── nu-core │ rs rake │ rb ─────────┴─────────── ``` ``` > echo [[lib, extension]; [nu-core, rs] [rake, rb]] | drop column ───────── lib ───────── nu-core rake ───────── ```
87 lines
2.2 KiB
Rust
87 lines
2.2 KiB
Rust
use crate::prelude::*;
|
|
use nu_data::base::select_fields;
|
|
use nu_engine::WholeStreamCommand;
|
|
use nu_errors::ShellError;
|
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape};
|
|
use nu_source::Tagged;
|
|
|
|
pub struct SubCommand;
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct Arguments {
|
|
columns: Option<Tagged<u64>>,
|
|
}
|
|
|
|
#[async_trait]
|
|
impl WholeStreamCommand for SubCommand {
|
|
fn name(&self) -> &str {
|
|
"drop column"
|
|
}
|
|
|
|
fn signature(&self) -> Signature {
|
|
Signature::build("drop column").optional(
|
|
"columns",
|
|
SyntaxShape::Number,
|
|
"starting from the end, the number of columns to remove",
|
|
)
|
|
}
|
|
|
|
fn usage(&self) -> &str {
|
|
"Remove the last number of columns. If you want to remove columns by name, try 'reject'."
|
|
}
|
|
|
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|
drop(args).await
|
|
}
|
|
|
|
fn examples(&self) -> Vec<Example> {
|
|
use nu_protocol::{row, Value};
|
|
|
|
vec![Example {
|
|
description: "Remove the last column of a table",
|
|
example: "echo [[lib, extension]; [nu-lib, rs] [nu-core, rb]] | drop column",
|
|
result: Some(vec![
|
|
row! { "lib".into() => Value::from("nu-lib") },
|
|
row! { "lib".into() => Value::from("nu-core") },
|
|
]),
|
|
}]
|
|
}
|
|
}
|
|
|
|
async fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|
let (Arguments { columns }, input) = args.process().await?;
|
|
|
|
let to_drop = if let Some(quantity) = columns {
|
|
*quantity as usize
|
|
} else {
|
|
1
|
|
};
|
|
|
|
Ok(input
|
|
.map(move |item| {
|
|
let headers = item.data_descriptors();
|
|
|
|
let descs = match headers.len() {
|
|
0 => &headers[..],
|
|
n if to_drop > n => &[],
|
|
n => &headers[..n - to_drop],
|
|
};
|
|
|
|
select_fields(&item, descs, item.tag())
|
|
})
|
|
.map(ReturnSuccess::value)
|
|
.to_output_stream())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn examples_work_as_expected() -> Result<(), ShellError> {
|
|
use crate::examples::test as test_examples;
|
|
|
|
test_examples(SubCommand {})
|
|
}
|
|
}
|