mirror of
https://github.com/nushell/nushell.git
synced 2025-02-16 18:41:44 +01:00
Prevents duplicate fields in transpose -r
(#5840)
This commit is contained in:
parent
0827ed143d
commit
f43a65d7a7
@ -15,6 +15,8 @@ pub struct TransposeArgs {
|
|||||||
header_row: bool,
|
header_row: bool,
|
||||||
ignore_titles: bool,
|
ignore_titles: bool,
|
||||||
as_record: bool,
|
as_record: bool,
|
||||||
|
keep_last: bool,
|
||||||
|
keep_all: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command for Transpose {
|
impl Command for Transpose {
|
||||||
@ -39,6 +41,16 @@ impl Command for Transpose {
|
|||||||
"transfer to record if the result is a table and contains only one row",
|
"transfer to record if the result is a table and contains only one row",
|
||||||
Some('d'),
|
Some('d'),
|
||||||
)
|
)
|
||||||
|
.switch(
|
||||||
|
"keep-last",
|
||||||
|
"on repetition of record fields due to `header-row`, keep the last value obtained",
|
||||||
|
Some('l'),
|
||||||
|
)
|
||||||
|
.switch(
|
||||||
|
"keep-all",
|
||||||
|
"on repetition of record fields due to `header-row`, keep all the values obtained",
|
||||||
|
Some('a'),
|
||||||
|
)
|
||||||
.rest(
|
.rest(
|
||||||
"rest",
|
"rest",
|
||||||
SyntaxShape::String,
|
SyntaxShape::String,
|
||||||
@ -149,6 +161,8 @@ pub fn transpose(
|
|||||||
header_row: call.has_flag("header-row"),
|
header_row: call.has_flag("header-row"),
|
||||||
ignore_titles: call.has_flag("ignore-titles"),
|
ignore_titles: call.has_flag("ignore-titles"),
|
||||||
as_record: call.has_flag("as-record"),
|
as_record: call.has_flag("as-record"),
|
||||||
|
keep_last: call.has_flag("keep-last"),
|
||||||
|
keep_all: call.has_flag("keep-all"),
|
||||||
rest: call.rest(engine_state, stack, 0)?,
|
rest: call.rest(engine_state, stack, 0)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -240,12 +254,82 @@ pub fn transpose(
|
|||||||
for i in input.clone() {
|
for i in input.clone() {
|
||||||
match &i.get_data_by_key(&desc) {
|
match &i.get_data_by_key(&desc) {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
cols.push(headers[column_num].clone());
|
if args.keep_all && cols.contains(&headers[column_num]) {
|
||||||
vals.push(x.clone());
|
let index = cols
|
||||||
|
.iter()
|
||||||
|
.position(|y| y == &headers[column_num])
|
||||||
|
.expect("value is contained.");
|
||||||
|
let new_val = match &vals[index] {
|
||||||
|
Value::List { vals, span } => {
|
||||||
|
let mut vals = vals.clone();
|
||||||
|
vals.push(x.clone());
|
||||||
|
Value::List {
|
||||||
|
vals: vals.to_vec(),
|
||||||
|
span: *span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v => Value::List {
|
||||||
|
vals: vec![v.clone(), x.clone()],
|
||||||
|
span: v.span().expect("this should be a valid span"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cols.remove(index);
|
||||||
|
vals.remove(index);
|
||||||
|
|
||||||
|
cols.push(headers[column_num].clone());
|
||||||
|
vals.push(new_val);
|
||||||
|
} else if args.keep_last && cols.contains(&headers[column_num]) {
|
||||||
|
let index = cols
|
||||||
|
.iter()
|
||||||
|
.position(|y| y == &headers[column_num])
|
||||||
|
.expect("value is contained.");
|
||||||
|
cols.remove(index);
|
||||||
|
vals.remove(index);
|
||||||
|
cols.push(headers[column_num].clone());
|
||||||
|
vals.push(x.clone());
|
||||||
|
} else if !cols.contains(&headers[column_num]) {
|
||||||
|
cols.push(headers[column_num].clone());
|
||||||
|
vals.push(x.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
cols.push(headers[column_num].clone());
|
if args.keep_all && cols.contains(&headers[column_num]) {
|
||||||
vals.push(Value::nothing(name));
|
let index = cols
|
||||||
|
.iter()
|
||||||
|
.position(|y| y == &headers[column_num])
|
||||||
|
.expect("value is contained.");
|
||||||
|
let new_val = match &vals[index] {
|
||||||
|
Value::List { vals, span } => {
|
||||||
|
let mut vals = vals.clone();
|
||||||
|
vals.push(Value::nothing(name));
|
||||||
|
Value::List {
|
||||||
|
vals: vals.to_vec(),
|
||||||
|
span: *span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v => Value::List {
|
||||||
|
vals: vec![v.clone(), Value::nothing(name)],
|
||||||
|
span: v.span().expect("this should be a valid span"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cols.remove(index);
|
||||||
|
vals.remove(index);
|
||||||
|
|
||||||
|
cols.push(headers[column_num].clone());
|
||||||
|
vals.push(new_val);
|
||||||
|
} else if args.keep_last && cols.contains(&headers[column_num]) {
|
||||||
|
let index = cols
|
||||||
|
.iter()
|
||||||
|
.position(|y| y == &headers[column_num])
|
||||||
|
.expect("value is contained.");
|
||||||
|
cols.remove(index);
|
||||||
|
vals.remove(index);
|
||||||
|
cols.push(headers[column_num].clone());
|
||||||
|
vals.push(Value::nothing(name));
|
||||||
|
} else if !cols.contains(&headers[column_num]) {
|
||||||
|
cols.push(headers[column_num].clone());
|
||||||
|
vals.push(Value::nothing(name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
column_num += 1;
|
column_num += 1;
|
||||||
|
@ -65,6 +65,7 @@ mod split_row;
|
|||||||
mod str_;
|
mod str_;
|
||||||
mod take;
|
mod take;
|
||||||
mod touch;
|
mod touch;
|
||||||
|
mod transpose;
|
||||||
mod uniq;
|
mod uniq;
|
||||||
mod update;
|
mod update;
|
||||||
mod upsert;
|
mod upsert;
|
||||||
|
37
crates/nu-command/tests/commands/transpose.rs
Normal file
37
crates/nu-command/tests/commands/transpose.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use nu_test_support::{nu, pipeline};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn row() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".", pipeline(
|
||||||
|
r#"
|
||||||
|
[[key value]; [foo 1] [foo 2]] | transpose -r | debug
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert!(actual.out.contains("foo: 1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn row_but_last() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".", pipeline(
|
||||||
|
r#"
|
||||||
|
[[key value]; [foo 1] [foo 2]] | transpose -r -l | debug
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert!(actual.out.contains("foo: 2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn row_but_all() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".", pipeline(
|
||||||
|
r#"
|
||||||
|
[[key value]; [foo 1] [foo 2]] | transpose -r -a | debug
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert!(actual.out.contains("foo: [1, 2]"));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user