From 9c779b071b4f24fe34e67602292c7afeb0cdbbc2 Mon Sep 17 00:00:00 2001 From: Jae-Heon Ji <32578710+jaeheonji@users.noreply.github.com> Date: Wed, 18 May 2022 23:49:34 +0900 Subject: [PATCH] feat: apply the `--numbered` option to acc in `reduce` command. (#5575) * feat: apply the `-n` option to acc * feat: update tests and examples --- crates/nu-command/src/filters/reduce.rs | 82 ++++++++++++++-------- crates/nu-command/tests/commands/reduce.rs | 6 +- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/crates/nu-command/src/filters/reduce.rs b/crates/nu-command/src/filters/reduce.rs index 772fe9f331..902f3ff7f7 100644 --- a/crates/nu-command/src/filters/reduce.rs +++ b/crates/nu-command/src/filters/reduce.rs @@ -51,7 +51,7 @@ impl Command for Reduce { }), }, Example { - example: "[ 1 2 3 ] | reduce -n {|it, acc| $acc + $it.item }", + example: "[ 1 2 3 ] | reduce -n {|it, acc| $acc.item + $it.item }", description: "Sum values of a list (same as 'math sum')", result: Some(Value::Int { val: 6, @@ -76,10 +76,10 @@ impl Command for Reduce { }, Example { example: r#"[ one longest three bar ] | reduce -n { |it, acc| - if ($it.item | str length) > ($acc | str length) { + if ($it.item | str length) > ($acc.item | str length) { $it.item } else { - $acc + $acc.item } }"#, description: "Find the longest string and its index", @@ -129,29 +129,22 @@ impl Command for Reduce { )); }; - let mut acc = start_val; + let mut acc = if numbered { + Value::Record { + cols: vec!["index".to_string(), "item".to_string()], + vals: vec![Value::Int { val: 0, span }, start_val], + span, + } + } else { + start_val + }; - let mut input_iter = input_iter.enumerate().peekable(); - while let Some((idx, x)) = input_iter.next() { - stack.with_env(&orig_env_vars, &orig_env_hidden); - // if the acc coming from previous iter is indexed, drop the index - acc = if let Value::Record { cols, vals, .. } = &acc { - if cols.len() == 2 && vals.len() == 2 { - if cols[0].eq("index") && cols[1].eq("item") { - vals[1].clone() - } else { - acc - } - } else { - acc - } - } else { - acc - }; - - if let Some(var) = block.signature.get_positional(0) { - if let Some(var_id) = &var.var_id { - let it = if numbered { + let mut input_iter = input_iter + .enumerate() + .map(|(idx, x)| { + if numbered { + ( + idx, Value::Record { cols: vec!["index".to_string(), "item".to_string()], vals: vec![ @@ -162,16 +155,45 @@ impl Command for Reduce { x, ], span, - } - } else { - x - }; + }, + ) + } else { + (idx, x) + } + }) + .peekable(); - stack.add_var(*var_id, it); + while let Some((idx, x)) = input_iter.next() { + stack.with_env(&orig_env_vars, &orig_env_hidden); + + if let Some(var) = block.signature.get_positional(0) { + if let Some(var_id) = &var.var_id { + stack.add_var(*var_id, x); } } + if let Some(var) = block.signature.get_positional(1) { if let Some(var_id) = &var.var_id { + acc = if numbered { + if let Value::Record { .. } = &acc { + acc + } else { + Value::Record { + cols: vec!["index".to_string(), "item".to_string()], + vals: vec![ + Value::Int { + val: idx as i64 + off, + span, + }, + acc, + ], + span, + } + } + } else { + acc + }; + stack.add_var(*var_id, acc); } } diff --git a/crates/nu-command/tests/commands/reduce.rs b/crates/nu-command/tests/commands/reduce.rs index 37555012db..fb496e8106 100644 --- a/crates/nu-command/tests/commands/reduce.rs +++ b/crates/nu-command/tests/commands/reduce.rs @@ -46,15 +46,13 @@ fn reduce_rows_example() { assert_eq!(actual.out, "14.8"); } -// FIXME: jt: needs more work -#[ignore] #[test] fn reduce_numbered_example() { let actual = nu!( cwd: ".", pipeline( r#" echo one longest three bar - | reduce -n { |it, acc| if ($it.item | str length) > ($acc | str length) {echo $it.item} else {echo $acc}} + | reduce -n { |it, acc| if ($it.item | str length) > ($acc.item | str length) {echo $it} else {echo $acc}} | get index "# ) @@ -69,7 +67,7 @@ fn reduce_numbered_integer_addition_example() { cwd: ".", pipeline( r#" echo [1 2 3 4] - | reduce -n { |it, acc| $acc + $it.item } + | reduce -n { |it, acc| $acc.item + $it.item } "# ) );