我正在尋找一種Vec用兩個謂詞對 a 進行磁區的方法:
- 一個用于第一個磁區點。例如 x > 3
- 一個用于磁區的最后一個元素。例如 x < 7
例如這個向量:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
有這個切片:
[4, 5, 6]
我想我可以像std 上partition_point的示例一樣使用兩次。但是是否有另一種方法(或板條箱)可以在第一個謂詞的第一個匹配和第二個謂詞的第一個匹配之間直接傳遞兩個謂詞和切片?
uj5u.com熱心網友回復:
如果您知道 slice 實際上實作了這種磁區,那么最好的辦法是使用雙重partition_point方法。
fn partition_twice_slice<T>(
vs: &[T],
start_pred: impl Fn(&T) -> bool,
end_pred: impl Fn(&T) -> bool,
) -> &[T] {
let start = vs.partition_point(start_pred);
let end = start vs[start..].partition_point(end_pred);
&vs[start..end]
}
如果您只需要滿足磁區要求的第一個切片,您可以獲得更多創意。
在迭代器上,您可以使用skip_whileand take_while:
fn partition_twice_iter<T>(
vs: Vec<T>,
start_pred: impl Fn(&T) -> bool,
end_pred: impl Fn(&T) -> bool,
) -> Vec<T> {
vs.into_iter()
.skip_while(|el| start_pred(el))
.take_while(|el| end_pred(el))
.collect()
}
如果您只需要切片,您可以調整它以找到系結索引:
fn partition_twice_slice<T>(
vs: &[T],
start_pred: impl Fn(&T) -> bool,
end_pred: impl Fn(&T) -> bool,
) -> &[T] {
let start = (0..vs.len())
.find(|&i| start_pred(&vs[i]))
.unwrap_or(vs.len());
let end = (start..vs.len())
.find(|&i| !end_pred(&vs[i]))
.unwrap_or(vs.len());
&vs[start..end]
}
示例用法:
fn main() {
assert_eq!(
partition_twice_iter(vec![1, 2, 3, 4, 5, 6, 7, 8, 9], |&x| x <= 3, |&x| x < 7),
vec![4, 5, 6]
);
assert_eq!(
partition_twice_slice(&[1, 2, 3, 4, 5, 6, 7, 8, 9], |&x| x <= 3, |&x| x < 7),
&[4, 5, 6]
);
}
請注意,我改變了您的x > 3要求以更好地適應partition_point.
uj5u.com熱心網友回復:
這對于自己實作非常簡單。它只是一個接受一個切片和兩個謂詞并回傳一個子切片的函式:
fn partition<T, P1, P2>(i: &[T], mut p1: P1, mut p2: P2) -> &[T]
where P1: FnMut(&T) -> bool,
P2: FnMut(&T) -> bool
{
let mut start: usize = 0;
while start < i.len() && !p1(&i[start]) {
start = 1;
}
let mut end = start;
while end < i.len() && p2(&i[end]) {
end = 1;
}
&i[start..end]
}
(游樂場)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/438477.html
上一篇:遍歷串列并添加到串列而不會引發ConcurrentModificationException-Java
下一篇:Ansible嵌套回圈,需要幫助
