我经常发现自己想要在某个结构或元组的属性上使用迭代器,所以我想知道如何正确地做到这一点。我目前有两个类型为$[(usize, &str)]的切片,我想检查它们各自的索引(usize)是否相等,这样在切片的每次迭代中都有tuple1.0 == tuple2.0。我该怎么做?
$[(usize, &str)]
usize
tuple1.0 == tuple2.0
8xiog9wr1#
如果我理解正确的话,你想检查给定的切片x和y,x[i].0 == y[i].0是否所有有效的i。您没有指定的一件事是,如果这些切片具有不同的长度,应该发生什么。我会假设,在这种情况下,它们是不相等的,但是如果你想要不同的东西,你可以改变它。你可以用很多方法来解决这个问题,我将分享一个使用迭代器的方法,它具有函数的味道。但是请注意,这可能与您自己编写for循环具有相同的性能。
x
y
x[i].0 == y[i].0
i
pub fn eq(x: &[(usize, &str)], y: &[(usize, &str)]) -> bool { if x.len() != y.len() { return false; } x.into_iter() .zip(y) .map(|((x_index, _), (y_index, _))| (x_index, y_index)) .all(|(x_index, y_index)| x_index == y_index) }
这段代码将x和y转换为迭代器,将它们压缩在一起,Map掉不需要的字符串切片(这一步不是必需的,我只是为了更好的可读性而添加它),最后检查所有元素的索引是否相等。
toiithl62#
我不知道你是想把这两个切片作为一个整体来比较,还是想把重点放在每对匹配的元素上。在这两种情况下,您都必须在两个切片上都进行扫描。这通常是用.zip()来完成的,以确保步调一致。请注意,为了方便起见,函数std::iter::zip()也是这样做的,并避免显式写入.iter()(它是在内部完成的)。如果只需要整个诊断,则.all()可以在.zip()上使用。另一方面,如果必须考虑每个匹配对,那么.filter()将只将这些对提供给通常的for循环(然后从这里开始,您可以对这个对做任何您想要的事情)。
.zip()
std::iter::zip()
.iter()
.all()
.filter()
for
fn equiv_whole_slices( a: &[(usize, &str)], b: &[(usize, &str)], ) { // let equiv = a.len() == b.len() // && a.iter() // .zip(b.iter()) // .all(|((a_i, _a_s), (b_i, _b_s))| a_i == b_i); let equiv = a.len() == b.len() && std::iter::zip(a, b).all(|((a_i, _a_s), (b_i, _b_s))| a_i == b_i); println!("comparing {:?}", a); println!(" against {:?}", b); println!(" ~~> {:?}", equiv); } fn each_equiv_elements( a: &[(usize, &str)], b: &[(usize, &str)], ) { println!("iterating over {:?}", a); println!(" and {:?}", b); // for (ta, tb) in a // .iter() // .zip(b.iter()) // .filter(|((a_i, _a_s), (b_i, _b_s))| a_i == b_i) for (ta, tb) in std::iter::zip(a, b).filter(|((a_i, _a_s), (b_i, _b_s))| a_i == b_i) { println!("• {:?} and {:?}", ta, tb); } } fn main() { let array_1 = [(0, "zero"), (1, "one"), (2, "two"), (3, "three")]; let array_2 = [(1, "AAA"), (2, "BBB"), (3, "CCC")]; equiv_whole_slices(&array_1[..3], &array_2); equiv_whole_slices(&array_1[1..], &array_2); equiv_whole_slices(&array_1[1..3], &array_2); each_equiv_elements(&array_1[..3], &array_2); each_equiv_elements(&array_1[1..], &array_2); each_equiv_elements(&array_1[1..3], &array_2); } /* comparing [(0, "zero"), (1, "one"), (2, "two")] against [(1, "AAA"), (2, "BBB"), (3, "CCC")] ~~> false comparing [(1, "one"), (2, "two"), (3, "three")] against [(1, "AAA"), (2, "BBB"), (3, "CCC")] ~~> true comparing [(1, "one"), (2, "two")] against [(1, "AAA"), (2, "BBB"), (3, "CCC")] ~~> false iterating over [(0, "zero"), (1, "one"), (2, "two")] and [(1, "AAA"), (2, "BBB"), (3, "CCC")] iterating over [(1, "one"), (2, "two"), (3, "three")] and [(1, "AAA"), (2, "BBB"), (3, "CCC")] • (1, "one") and (1, "AAA") • (2, "two") and (2, "BBB") • (3, "three") and (3, "CCC") iterating over [(1, "one"), (2, "two")] and [(1, "AAA"), (2, "BBB"), (3, "CCC")] • (1, "one") and (1, "AAA") • (2, "two") and (2, "BBB") */
a0x5cqrl3#
迭代器有一个eq()方法,用于检查两个迭代器是否产生完全相同的项。你可以用它来比较两个切片中的“索引”是否相同:
eq()
fn indices_match(a: &[(usize, &str)], b: &[(usize, &str)]) -> bool { a.iter().map(|&(i, _)| i).eq(b.iter().map(|&(i, _)| i)) }
这隐式地检查切片是否具有相等的长度。
3条答案
按热度按时间8xiog9wr1#
如果我理解正确的话,你想检查给定的切片
x
和y
,x[i].0 == y[i].0
是否所有有效的i
。您没有指定的一件事是,如果这些切片具有不同的长度,应该发生什么。我会假设,在这种情况下,它们是不相等的,但是如果你想要不同的东西,你可以改变它。
你可以用很多方法来解决这个问题,我将分享一个使用迭代器的方法,它具有函数的味道。但是请注意,这可能与您自己编写for循环具有相同的性能。
这段代码将
x
和y
转换为迭代器,将它们压缩在一起,Map掉不需要的字符串切片(这一步不是必需的,我只是为了更好的可读性而添加它),最后检查所有元素的索引是否相等。toiithl62#
我不知道你是想把这两个切片作为一个整体来比较,还是想把重点放在每对匹配的元素上。
在这两种情况下,您都必须在两个切片上都进行扫描。这通常是用
.zip()
来完成的,以确保步调一致。请注意,为了方便起见,函数std::iter::zip()
也是这样做的,并避免显式写入.iter()
(它是在内部完成的)。如果只需要整个诊断,则
.all()
可以在.zip()
上使用。另一方面,如果必须考虑每个匹配对,那么.filter()
将只将这些对提供给通常的for
循环(然后从这里开始,您可以对这个对做任何您想要的事情)。a0x5cqrl3#
迭代器有一个
eq()
方法,用于检查两个迭代器是否产生完全相同的项。你可以用它来比较两个切片中的“索引”是否相同:这隐式地检查切片是否具有相等的长度。