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: "[ 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);
}
}

View file

@ -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 }
"#
)
);