内容的栏目 * @param int $category 0列表 1频道 2单页 3外链 * @return array */ function category_list($forumlist, $model = 0, $display = 0, $category = 0) { if (empty($forumlist)) return NULL; static $cache = array(); $key = $model . '-' . $display . '-' . $category; if (isset($cache[$key])) return $cache[$key]; if ($display) { foreach ($forumlist as $k => $val) { if (1 == $val['display'] && 1 == $val['type'] && $val['category'] == $category) { $cache[$key][$k] = $val; } } } else { foreach ($forumlist as $k => $val) { if (1 == $val['type'] && $val['category'] == $category) { $cache[$key][$k] = $val; } } } return empty($cache[$key]) ? NULL : $cache[$key]; } /** * @param $forumlist 所有版块列表 不分模型 * @param int $display 0全部CMS栏目 1在首页和频道显示内容的栏目 * @param int $category 0列表 1频道 2单页 3外链 * @return array */ function category_list_show($forumlist, $display = 0, $category = 0) { if (empty($forumlist)) return NULL; static $cache = array(); $key = $display . '-' . $category; if (isset($cache[$key])) return $cache[$key]; if ($display) { foreach ($forumlist as $k => $val) { if (1 == $val['display'] && 1 == $val['type'] && $val['category'] == $category) { $cache[$key][$k] = $val; } } } else { foreach ($forumlist as $k => $val) { if (1 == $val['type'] && $val['category'] == $category) { $cache[$key][$k] = $val; } } } return empty($cache[$key]) ? NULL : $cache[$key]; } /** * @param $forumlist 所有版块列表 * @return mixed BBS栏目数据(仅列表) 尚未开放bbs频道功能 */ function forum_list($forumlist) { if (empty($forumlist)) return array(); static $cache = array(); if (isset($cache['bbs_forum_list'])) return $cache['bbs_forum_list']; $cache['bbs_forum_list'] = array(); foreach ($forumlist as $_fid => $_forum) { if ($_forum['type']) continue; $cache['bbs_forum_list'][$_fid] = $_forum; } return $cache['bbs_forum_list']; } // 导航显示的版块 function nav_list($forumlist) { if (empty($forumlist)) return NULL; static $cache = array(); if (isset($cache['nav_list'])) return $cache['nav_list']; foreach ($forumlist as $fid => $forum) { if (0 == $forum['nav_display']) { unset($forumlist[$fid]); } } return $cache['nav_list'] = $forumlist; } ?>rust - DoubleEndedIterator for Vec - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

rust - DoubleEndedIterator for Vec - Stack Overflow

programmeradmin0浏览0评论

How to check if a given list/range is a suffix of another range/list. I tried to implement this using DoubleEndedIterator trait which provides facility of backward iteration. But the Vec collection from Rust standard library doesn't implement DoubleEndedIterator trait.

use std::iter::Peekable;

pub fn ends_with<'a, 'b, FirstList, FirstItemType, SecondList, SecondItemType, BinaryPredicate>(
    first_list: FirstList,
    second_list: SecondList,
    binary_predicate: BinaryPredicate) -> bool
where
    FirstList: IntoIterator<Item = &'a FirstItemType>,
    FirstList: DoubleEndedIterator<Item = &'a FirstItemType>,
    FirstItemType: 'a,
    SecondList: IntoIterator<Item = &'b SecondItemType>,
    SecondList: DoubleEndedIterator<Item = &'b SecondItemType>,
    SecondItemType: 'b,
    BinaryPredicate: Fn(&FirstItemType, &SecondItemType) -> bool
{
    let mut f_itr = first_list.rev().into_iter().peekable();
    let mut s_itr = second_list.rev().into_iter().peekable();

    while let (Some(f), Some(s)) = (f_itr.peek(), s_itr.peek()) {
        if !binary_predicate(*f, *s) {
            return false;
        }
        let _ = f_itr.next();
        let _ = s_itr.next();
    }

    f_itr.peek().is_some() || s_itr.peek().is_none()
}

fn main() {
    let first_list = vec![1, 2, 3, 4, 5, 6];
    let second_list = vec![4, 5, 6];

    let res = ends_with(&first_list, &second_list, |first_item, second_item| {
        *first_item == *second_item
    });

    assert!(res);
}

Error

error[E0277]: the trait bound `&Vec<{integer}>: DoubleEndedIterator` is not satisfied
  --> src/main.rs:34:29
   |
34 |     let mut res = ends_with(&first_list, &second_list, |first_item, second_item| {
   |                   --------- ^^^^^^^^^^^ the trait `DoubleEndedIterator` is not implemented for `&Vec<{integer}>`
   |                   |
   |                   required by a bound introduced by this call
   |
note: required by a bound in `ends_with`
  --> src/main.rs:9:16
   |
3  | pub fn ends_with<'a, 'b, FirstList, FirstItemType, SecondList, SecondItemType, BinaryPredicate>(
   |        --------- required by a bound in this function
...
9  |     FirstList: DoubleEndedIterator<Item = &'a FirstItemType>,
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ends_with`

error[E0277]: the trait bound `&Vec<{integer}>: DoubleEndedIterator` is not satisfied
  --> src/main.rs:34:42
   |
34 |     let mut res = ends_with(&first_list, &second_list, |first_item, second_item| {
   |                   ---------              ^^^^^^^^^^^^ the trait `DoubleEndedIterator` is not implemented for `&Vec<{integer}>`
   |                   |
   |                   required by a bound introduced by this call
   |
note: required by a bound in `ends_with`
  --> src/main.rs:12:17
   |
3  | pub fn ends_with<'a, 'b, FirstList, FirstItemType, SecondList, SecondItemType, BinaryPredicate>(
   |        --------- required by a bound in this function
...
12 |     SecondList: DoubleEndedIterator<Item = &'b SecondItemType>,
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ends_with`

For more information about this error, try `rustc --explain E0277`.

How to check if a given list/range is a suffix of another range/list. I tried to implement this using DoubleEndedIterator trait which provides facility of backward iteration. But the Vec collection from Rust standard library doesn't implement DoubleEndedIterator trait.

use std::iter::Peekable;

pub fn ends_with<'a, 'b, FirstList, FirstItemType, SecondList, SecondItemType, BinaryPredicate>(
    first_list: FirstList,
    second_list: SecondList,
    binary_predicate: BinaryPredicate) -> bool
where
    FirstList: IntoIterator<Item = &'a FirstItemType>,
    FirstList: DoubleEndedIterator<Item = &'a FirstItemType>,
    FirstItemType: 'a,
    SecondList: IntoIterator<Item = &'b SecondItemType>,
    SecondList: DoubleEndedIterator<Item = &'b SecondItemType>,
    SecondItemType: 'b,
    BinaryPredicate: Fn(&FirstItemType, &SecondItemType) -> bool
{
    let mut f_itr = first_list.rev().into_iter().peekable();
    let mut s_itr = second_list.rev().into_iter().peekable();

    while let (Some(f), Some(s)) = (f_itr.peek(), s_itr.peek()) {
        if !binary_predicate(*f, *s) {
            return false;
        }
        let _ = f_itr.next();
        let _ = s_itr.next();
    }

    f_itr.peek().is_some() || s_itr.peek().is_none()
}

fn main() {
    let first_list = vec![1, 2, 3, 4, 5, 6];
    let second_list = vec![4, 5, 6];

    let res = ends_with(&first_list, &second_list, |first_item, second_item| {
        *first_item == *second_item
    });

    assert!(res);
}

Error

error[E0277]: the trait bound `&Vec<{integer}>: DoubleEndedIterator` is not satisfied
  --> src/main.rs:34:29
   |
34 |     let mut res = ends_with(&first_list, &second_list, |first_item, second_item| {
   |                   --------- ^^^^^^^^^^^ the trait `DoubleEndedIterator` is not implemented for `&Vec<{integer}>`
   |                   |
   |                   required by a bound introduced by this call
   |
note: required by a bound in `ends_with`
  --> src/main.rs:9:16
   |
3  | pub fn ends_with<'a, 'b, FirstList, FirstItemType, SecondList, SecondItemType, BinaryPredicate>(
   |        --------- required by a bound in this function
...
9  |     FirstList: DoubleEndedIterator<Item = &'a FirstItemType>,
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ends_with`

error[E0277]: the trait bound `&Vec<{integer}>: DoubleEndedIterator` is not satisfied
  --> src/main.rs:34:42
   |
34 |     let mut res = ends_with(&first_list, &second_list, |first_item, second_item| {
   |                   ---------              ^^^^^^^^^^^^ the trait `DoubleEndedIterator` is not implemented for `&Vec<{integer}>`
   |                   |
   |                   required by a bound introduced by this call
   |
note: required by a bound in `ends_with`
  --> src/main.rs:12:17
   |
3  | pub fn ends_with<'a, 'b, FirstList, FirstItemType, SecondList, SecondItemType, BinaryPredicate>(
   |        --------- required by a bound in this function
...
12 |     SecondList: DoubleEndedIterator<Item = &'b SecondItemType>,
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ends_with`

For more information about this error, try `rustc --explain E0277`.
Share Improve this question edited Feb 2 at 10:16 cafce25 27.6k5 gold badges45 silver badges58 bronze badges asked Feb 2 at 4:27 HarryHarry 3,1421 gold badge24 silver badges46 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

You want to put the DoubleEndedIterator bound on the iterator type, not on the iterable type (i.e., the type that implements IntoIterator). For example, for FirstList, you need to write the bound as FirstList::IntoIter: DoubleEndedIterator<Item = &'a FirstItemType>,. IntoIter is an associated type defined on the IntoIterator trait.

Also, first_list.rev().into_iter().peekable() needs to be changed to first_list.into_iter().rev().peekable() because rev() is not defined by the IntoIterator trait.

pub fn ends_with<'a, 'b, FirstList, FirstItemType, SecondList, SecondItemType, BinaryPredicate>(
    first_list: FirstList,
    second_list: SecondList,
    binary_predicate: BinaryPredicate,
) -> bool
where
    FirstList: IntoIterator<Item = &'a FirstItemType>,
    FirstList::IntoIter: DoubleEndedIterator<Item = &'a FirstItemType>,
    FirstItemType: 'a,
    SecondList: IntoIterator<Item = &'b SecondItemType>,
    SecondList::IntoIter: DoubleEndedIterator<Item = &'b SecondItemType>,
    SecondItemType: 'b,
    BinaryPredicate: Fn(&FirstItemType, &SecondItemType) -> bool,
{
    let mut f_itr = first_list.into_iter().rev().peekable();
    let mut s_itr = second_list.into_iter().rev().peekable();

    while let (Some(f), Some(s)) = (f_itr.peek(), s_itr.peek()) {
        if !binary_predicate(*f, *s) {
            return false;
        }
        let _ = f_itr.next();
        let _ = s_itr.next();
    }

    f_itr.peek().is_some() || s_itr.peek().is_none()
}

fn main() {
    let first_list = vec![1, 2, 3, 4, 5, 6];
    let second_list = vec![4, 5, 6];

    let res = ends_with(&first_list, &second_list, |first_item, second_item| {
        *first_item == *second_item
    });

    assert!(res);
}
发布评论

评论列表(0)

  1. 暂无评论