forked from extern/nushell
Make reduce -n
more sensible (#4791)
This commit is contained in:
parent
088d19ad47
commit
fac086c826
@ -1,3 +1,5 @@
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use nu_engine::{eval_block, CallExt};
|
||||
|
||||
use nu_protocol::ast::Call;
|
||||
@ -69,19 +71,9 @@ impl Command for Reduce {
|
||||
}
|
||||
}"#,
|
||||
description: "Find the longest string and its index",
|
||||
result: Some(Value::Record {
|
||||
cols: vec!["index".to_string(), "item".to_string()],
|
||||
vals: vec![
|
||||
Value::Int {
|
||||
val: 3,
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::String {
|
||||
result: Some(Value::String {
|
||||
val: "longest".to_string(),
|
||||
span: Span::test_data(),
|
||||
},
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
]
|
||||
@ -94,10 +86,6 @@ impl Command for Reduce {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
// TODO: How to make this interruptible?
|
||||
// TODO: Change the vars to $acc and $it instead of $it.acc and $it.item
|
||||
// (requires parser change)
|
||||
|
||||
let span = call.head;
|
||||
|
||||
let fold: Option<Value> = call.get_flag(engine_state, stack, "fold")?;
|
||||
@ -105,6 +93,7 @@ impl Command for Reduce {
|
||||
let capture_block: CaptureBlock = call.req(engine_state, stack, 0)?;
|
||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let orig_env_vars = stack.env_vars.clone();
|
||||
let orig_env_hidden = stack.env_hidden.clone();
|
||||
@ -126,13 +115,12 @@ impl Command for Reduce {
|
||||
));
|
||||
};
|
||||
|
||||
Ok(input_iter
|
||||
.enumerate()
|
||||
.fold(start_val, move |acc, (idx, x)| {
|
||||
stack.with_env(&orig_env_vars, &orig_env_hidden);
|
||||
let mut acc = start_val;
|
||||
|
||||
for (idx, x) in input_iter.enumerate() {
|
||||
stack.with_env(&orig_env_vars, &orig_env_hidden);
|
||||
// if the acc coming from previous iter is indexed, drop the index
|
||||
let acc = if let Value::Record { cols, vals, .. } = &acc {
|
||||
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()
|
||||
@ -173,37 +161,24 @@ impl Command for Reduce {
|
||||
}
|
||||
}
|
||||
|
||||
let v = match eval_block(
|
||||
acc = eval_block(
|
||||
engine_state,
|
||||
&mut stack,
|
||||
block,
|
||||
PipelineData::new(span),
|
||||
redirect_stdout,
|
||||
redirect_stderr,
|
||||
) {
|
||||
Ok(v) => v.into_value(span),
|
||||
Err(error) => Value::Error { error },
|
||||
};
|
||||
)?
|
||||
.into_value(span);
|
||||
|
||||
if numbered {
|
||||
// make sure the output is indexed
|
||||
Value::Record {
|
||||
cols: vec!["index".to_string(), "item".to_string()],
|
||||
vals: vec![
|
||||
Value::Int {
|
||||
val: idx as i64 + off,
|
||||
span,
|
||||
},
|
||||
v,
|
||||
],
|
||||
span,
|
||||
if let Some(ctrlc) = &ctrlc {
|
||||
if ctrlc.load(Ordering::SeqCst) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
v
|
||||
}
|
||||
})
|
||||
.with_span(span)
|
||||
.into_pipeline_data())
|
||||
}
|
||||
|
||||
Ok(acc.with_span(span).into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,6 @@ fn reduce_numbered_integer_addition_example() {
|
||||
r#"
|
||||
echo [1 2 3 4]
|
||||
| reduce -n { |it, acc| $acc + $it.item }
|
||||
| get item
|
||||
"#
|
||||
)
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user