【问题标题】:How to access index in position method of iter?如何在iter的位置方法中访问索引?
【发布时间】:2020-11-29 14:59:33
【问题描述】:

我正在尝试打印数组中第一个不完全是 1 大于前一个数字的数字(在以下示例中,预期结果是 7)。

我写了&n > 0 && 以避免在第一个数字之前检查(不存在的)数字。

fn main() {
    let numbers = [4, 5, 7];
    let result = numbers.iter().position(|&n| &n > 0 && n != numbers[&n - 1] + 1);
    println!("{:?}", result);
}

我收到关于 0 的编译器错误:

预期的参考,找到整数

帮助:考虑在这里借用:&0

基本上我正在尝试做这个 JavaScript 所做的事情:

numbers.find((n, i) => i && n != numbers[i - 1] + 1);

谁能告诉我我做错了什么?

我假设 n 是值,&n 是索引。如果这不正确,那么我如何在 Lamba 中获取索引?

【问题讨论】:

    标签: arrays lambda rust iterator


    【解决方案1】:

    另一种查看切片中每对两个连续项目的方法windows(2) iterator

    fn find_non_consecutive(a: &[i32]) -> Option<i32> {
        a.windows(2).find(|x| x[0] + 1 != x[1]).map(|x| x[1])
    }
    

    【讨论】:

    • 你忘了写return吗?
    • @GirkovArpa 不,因为没有尾随分号,表达式就是返回值。
    • 以前没见过windows——非常好用,会记住的!
    【解决方案2】:

    position 用于搜索元素。由于您需要检查数组中的所有元素,请改用enumerate 来访问元素索引和值:

    fn main() {
        let numbers = [4, 5, 7];
        let result = numbers.iter().enumerate().filter_map(|(i, &n)| {
            if i > 0 && n != numbers[i-1] + 1 {
                Some(n)
            } else {
                None
            }
        });
        println!("{:?}", result.collect::<Vec<i32>>());
    }
    

    Playground.

    如果你只需要找到第一个这样的元素,你可以使用find_map而不是filter_map

    fn main() {
        let numbers = [4, 5, 7];
        let result = numbers.iter().enumerate().find_map(|(i, &n)| {
            if i > 0 && n != numbers[i-1] + 1 {
                Some(n)
            } else {
                None
            }
        });
        println!("{:?}", result);
    }
    

    【讨论】:

      【解决方案3】:

      如果你看一下Iterator::position的签名,你会发现它的predicate闭包参数实现了FnMut(Self::Item) -&gt; bool

      换句话说,您的参数&amp;n&lt;numbers.iter() as Iterator&gt;::Item 类型,即&amp;i32(对numbers 元素的引用)。 Iterator::position 不为其 predicate 闭包提供对迭代索引的访问权限——正如 Psidom 所展示的那样,Iterator::enumerate 就是这样做的。

      但是,我建议索引numbers 数组并不是解决此问题的一种非常惯用的方法。如果不出意外,它不能更普遍地应用于其他迭代。也许取而代之的是在数组上使用两个迭代器,一个更远的元素,将它们压缩并成对比较它们的元素?

      fn main() {
          let numbers = [4, 5, 7];
          
          let first = numbers.iter();
          let second = numbers.iter().skip(1);
          
          let result = first.zip(second)
              .find_map(|(&a, &b)| if b == a + 1 { None } else { Some(b) });
          
          println!("{:?}", result);
      }
      

      playground 上查看。

      【讨论】:

        【解决方案4】:

        我努力创建一个可以随心所欲使用的单独函数,所以最终工作的结果如下:

        fn find_non_consecutive(array_of_numbers: &[i32; 3]) -> Option<i32> {
            let result = array_of_numbers.iter().enumerate().find_map(|(i, &n)| {
                if i > 0 && n != array_of_numbers[i - 1] + 1 {
                    Some(n)
                } else {
                    None
                }
            });
            return result;
        }
        
        fn main() {
            let numbers: [i32; 3] = [4, 5, 7];
            let result = find_non_consecutive(&numbers);
            println!("{:?}", result); // Some(7)
        }
        

        【讨论】:

          猜你喜欢
          • 2016-09-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-30
          • 2016-12-13
          • 1970-01-01
          • 2019-07-03
          • 2018-06-01
          相关资源
          最近更新 更多