mirror of
https://github.com/nushell/nushell
synced 2024-12-25 12:33:17 +00:00
reject
multiple row args support (#10163)
# Description This PR fixes `reject` failing when providing row items in ascending order. # User-Facing Changes users can now `reject` multiple rows independently of each other. ```nushell let foo = [[a b]; [ 1 2] [3 4] [ 5 6]] # this will work independant of the order print ($foo | reject 2 1) print ($foo | reject 1 2) ``` --------- Co-authored-by: Antoine Stevan <44101798+amtoine@users.noreply.github.com>
This commit is contained in:
parent
17abbdf6e0
commit
248aca7a44
2 changed files with 70 additions and 7 deletions
|
@ -1,10 +1,12 @@
|
|||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::{Call, CellPath};
|
||||
use nu_protocol::ast::{Call, CellPath, PathMember};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
Category, Example, IntoPipelineData, PipelineData, Record, ShellError, Signature, Span,
|
||||
SyntaxShape, Type, Value,
|
||||
};
|
||||
use std::cmp::Reverse;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Reject;
|
||||
|
@ -70,6 +72,17 @@ impl Command for Reject {
|
|||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Reject a row in a table",
|
||||
example: "[[a, b]; [1, 2] [3, 4]] | reject 1",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
cols: vec!["a".to_string(), "b".to_string()],
|
||||
vals: vec![Value::test_int(1), Value::test_int(2)],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Reject the specified field in a record",
|
||||
example: "{a: 1, b: 2} | reject a",
|
||||
|
@ -99,15 +112,47 @@ fn reject(
|
|||
input: PipelineData,
|
||||
cell_paths: Vec<CellPath>,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let mut unique_rows: HashSet<usize> = HashSet::new();
|
||||
let val = input.into_value(span);
|
||||
let mut val = val;
|
||||
let mut columns = vec![];
|
||||
for c in cell_paths {
|
||||
if !columns.contains(&c) {
|
||||
columns.push(c);
|
||||
}
|
||||
let mut new_columns = vec![];
|
||||
let mut new_rows = vec![];
|
||||
for column in cell_paths {
|
||||
let CellPath { ref members } = column;
|
||||
match members.get(0) {
|
||||
Some(PathMember::Int { val, span, .. }) => {
|
||||
if members.len() > 1 {
|
||||
return Err(ShellError::GenericError(
|
||||
"Reject only allows row numbers for rows".into(),
|
||||
"extra after row number".into(),
|
||||
Some(*span),
|
||||
None,
|
||||
Vec::new(),
|
||||
));
|
||||
}
|
||||
if !unique_rows.contains(val) {
|
||||
unique_rows.insert(*val);
|
||||
new_rows.push(column);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if !new_columns.contains(&column) {
|
||||
new_columns.push(column)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
for cell_path in columns {
|
||||
new_rows.sort_unstable_by_key(|k| {
|
||||
Reverse({
|
||||
match k.members[0] {
|
||||
PathMember::Int { val, .. } => val,
|
||||
PathMember::String { .. } => usize::MIN,
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
new_columns.append(&mut new_rows);
|
||||
for cell_path in new_columns {
|
||||
val.remove_data_at_cell_path(&cell_path.members)?;
|
||||
}
|
||||
Ok(val.into_pipeline_data())
|
||||
|
|
|
@ -79,6 +79,12 @@ fn ignores_duplicate_columns_rejected() {
|
|||
assert_eq!(actual.out, "last name");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignores_duplicate_rows_rejected() {
|
||||
let actual = nu!("[[a,b];[1 2] [3 4] [5 6]] | reject 2 2 | to nuon");
|
||||
assert_eq!(actual.out, "[[a, b]; [1, 2], [3, 4]]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reject_record_from_raw_eval() {
|
||||
let actual = nu!(r#"{"a": 3} | reject a | describe"#);
|
||||
|
@ -143,3 +149,15 @@ fn reject_optional_row() {
|
|||
let actual = nu!("[{foo: 'bar'}] | reject 3? | to nuon");
|
||||
assert_eq!(actual.out, "[[foo]; [bar]]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reject_multiple_rows_ascending() {
|
||||
let actual = nu!("[[a,b];[1 2] [3 4] [5 6]] | reject 1 2 | to nuon");
|
||||
assert_eq!(actual.out, "[[a, b]; [1, 2]]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reject_multiple_rows_descending() {
|
||||
let actual = nu!("[[a,b];[1 2] [3 4] [5 6]] | reject 2 1 | to nuon");
|
||||
assert_eq!(actual.out, "[[a, b]; [1, 2]]");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue