feat: apply the --numbered option to acc in reduce command. (#5575)

* feat: apply the `-n` option to acc

* feat: update tests and examples
This commit is contained in:
Jae-Heon Ji 2022-05-18 23:49:34 +09:00 committed by GitHub
parent 1e94793df5
commit 9c779b071b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 34 deletions

View File

@ -51,7 +51,7 @@ impl Command for Reduce {
}), }),
}, },
Example { 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')", description: "Sum values of a list (same as 'math sum')",
result: Some(Value::Int { result: Some(Value::Int {
val: 6, val: 6,
@ -76,10 +76,10 @@ impl Command for Reduce {
}, },
Example { Example {
example: r#"[ one longest three bar ] | reduce -n { |it, acc| 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 $it.item
} else { } else {
$acc $acc.item
} }
}"#, }"#,
description: "Find the longest string and its index", 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 {
let mut input_iter = input_iter.enumerate().peekable(); cols: vec!["index".to_string(), "item".to_string()],
while let Some((idx, x)) = input_iter.next() { vals: vec![Value::Int { val: 0, span }, start_val],
stack.with_env(&orig_env_vars, &orig_env_hidden); span,
// 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 { } else {
acc start_val
}
} else {
acc
}; };
if let Some(var) = block.signature.get_positional(0) { let mut input_iter = input_iter
if let Some(var_id) = &var.var_id { .enumerate()
let it = if numbered { .map(|(idx, x)| {
if numbered {
(
idx,
Value::Record { Value::Record {
cols: vec!["index".to_string(), "item".to_string()], cols: vec!["index".to_string(), "item".to_string()],
vals: vec![ vals: vec![
@ -162,16 +155,45 @@ impl Command for Reduce {
x, x,
], ],
span, span,
} },
)
} else { } else {
x (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) = block.signature.get_positional(1) {
if let Some(var_id) = &var.var_id { 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); stack.add_var(*var_id, acc);
} }
} }

View File

@ -46,15 +46,13 @@ fn reduce_rows_example() {
assert_eq!(actual.out, "14.8"); assert_eq!(actual.out, "14.8");
} }
// FIXME: jt: needs more work
#[ignore]
#[test] #[test]
fn reduce_numbered_example() { fn reduce_numbered_example() {
let actual = nu!( let actual = nu!(
cwd: ".", pipeline( cwd: ".", pipeline(
r#" r#"
echo one longest three bar 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 | get index
"# "#
) )
@ -69,7 +67,7 @@ fn reduce_numbered_integer_addition_example() {
cwd: ".", pipeline( cwd: ".", pipeline(
r#" r#"
echo [1 2 3 4] echo [1 2 3 4]
| reduce -n { |it, acc| $acc + $it.item } | reduce -n { |it, acc| $acc.item + $it.item }
"# "#
) )
); );