< 返回版块

苦瓜小仔 发表于 2021-06-20 14:29

我正在写一个 mdbook 的 preprocessor ,需要从默认配置的文件名字符串中反查枚举类型。

然而 slice::binary_search_by_key 不能正常工作。

fn main() {
    // dbg!(&CSSFILES);
    let a = CssFile::variant("index.hbs");
    dbg!(&a); 
}
#[rustfmt::skip]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum CssFile {
    Variables, General, Chrome, Index, PagetocJs, Invalid,
    PagetocCss, Pagetoc, Custom(&'static str)
}

#[rustfmt::skip]
macro_rules! default {
    ($idt:ident, $e1:expr) => { (CssFile::$idt, $e1) };
    // 省略无关代码
}

// TODO: add more
#[rustfmt::skip]
pub static CSSFILES: &[(CssFile, &'static str)] =
    &[default!(Variables, "css/variables.css"),
      default!(Index,     "index.hbs"),
      default!(Pagetoc,   ""),
      default!(Invalid,   "") ];

impl CssFile {
    pub fn variant(filename: &str) -> Self {
        let index = CSSFILES.binary_search_by_key(&filename, |&(_, b)| b); // index: Result<usize, usize>
        dbg!(&filename, &index); // index 的查询结果是 Err(4) ,而实际上应该查到 OK(1)
        CSSFILES[index.unwrap()].0
    }
}

修正之后的代码:

impl CssFile {
    pub fn variant(filename: &str) -> Self {
        CSSFILES.iter().find(|&(_, f)| &filename == f).unwrap().0
    }
}

评论区

写评论
作者 苦瓜小仔 2021-06-20 14:48

哦~没看见 sorted 这个词。。。

感谢~

--
👇
johnmave126: 二分搜索需要是有序数组,你这里面空串在后,序是乱的不能二分。

以及你如果数组比较小的话,建议直接线性搜索,v.iter().find(x)这种。

如果数组比较大,可以考虑用string做key建一个hashmap

johnmave126 2021-06-20 14:44

二分搜索需要是有序数组,你这里面空串在后,序是乱的不能二分。

以及你如果数组比较小的话,建议直接线性搜索,v.iter().find(x)这种。

如果数组比较大,可以考虑用string做key建一个hashmap

1 共 2 条评论, 1 页