Vec> 的惯用 Rust筛选

发布于 2025-01-09 23:12:56 字数 2223 浏览 1 评论 0 原文

对编程非常陌生,出于某种原因,我选择了 rust,但我离题了...

当前代码引用 vec 字符串,将一个“列”与某个数组进行比较,并返回行和截断版本行。

下面的代码可以编译,但我在所有函数中不断重复使用相同的逻辑,并且对于某种闭包来说非常有用。

fn niacs(vec:&Vec<Vec<String>>, naics: Vec<&str> ) -> (Vec<Vec<String>>,Vec<Vec<String>>) {
    let mut return_vec_truncated = vec![];
    let mut return_vec_full = vec![];
    let mut contains_naice = false;

    
    for i in vec.iter() {
        for naic in naics.iter(){
            if i[31] == *naic {
                contains_naice = true;
            }
        
            if contains_naice {
                let x = info_wanted(&i);
                return_vec_truncated.push(x);
                return_vec_full.push(i.clone());
            }
            contains_naice = false;
    }
}
     (return_vec_full, return_vec_truncated)
}

我想要做的是写一些类似的内容:

let x = vec.iter().map(|x| x.iter()).filter(|x| x != naics);

问题是..我不想映射每个元素的所有元素,我只想在内部 vec 中跨一列,即列31、

Vec的样本Vec:

["471", "001020887", "", "1SNH0", "", "A", "Z2", "20020312", "20210711"、"20200731"、"20200731"、"基准国际有限公司"、""、""、""、"5025 海盗湾路"、""、"杰克逊维尔"、"佛罗里达"、"32210"、 “8309”、“美国”、“04”、 “19990208”、“1231”、“http://www.bmiint.com”、“2L”、“VA”、“美国”、“0005”、“27~2X~A5~QF~XS”、“541611 "、""、"0002"、"541611Y~541690Y"、"0000"、""、"N"、 "", "5025 海盗湾路", "", "杰克逊维尔", "32210", "8309", "美国", "佛罗里达", "安娜", "", "麦肯齐", "", "5025 海盗COVE RD"、""、"杰克逊维尔"、"32210"、"8309"、"美国"、 "FL"、"4437170460"、""、""、""、"[电子邮件受保护]"], ["472", "001021310", "", "94867", "", "A", "Z2", “19980424”、“20210323”、“20200323”、“20200323”、“丘吉尔公司”、“”、“”、“”、“富兰克林街 344 号”、“”、“梅尔罗斯”、“MA”、“02176” 、“1825”、“美国”、“05”、 "19480101"、"0731"、""、"2L"、"MA"、"美国"、"0002"、"2X~MF"、"332322"、""、"0001"、"332322Y"、"0000 "、""、"Y"、""、"POBOX 761038"、""、"梅尔罗斯"、 “02176”、“1825”、“美国”、“MA”、“马歇尔”、“W”、“SCHERMERHORN”、“”、“邮政信箱 761038”、“富兰克林街 344 号”、“梅尔罗斯”、“02176” , "", "美国", "MA", "7816654700", "", "", "7816625291", "[电子邮件受保护]"]]

Very new to programming and for some reason i chose rust to start with but i digress...

Current code to take a reference to a vec of vec strings, compare one 'Column' against some array and return the row and a truncated version of the row.

The below compiles, but i keep re-using this same logic across all my functions and would be really useful to just have some kind of closure.

fn niacs(vec:&Vec<Vec<String>>, naics: Vec<&str> ) -> (Vec<Vec<String>>,Vec<Vec<String>>) {
    let mut return_vec_truncated = vec![];
    let mut return_vec_full = vec![];
    let mut contains_naice = false;

    
    for i in vec.iter() {
        for naic in naics.iter(){
            if i[31] == *naic {
                contains_naice = true;
            }
        
            if contains_naice {
                let x = info_wanted(&i);
                return_vec_truncated.push(x);
                return_vec_full.push(i.clone());
            }
            contains_naice = false;
    }
}
     (return_vec_full, return_vec_truncated)
}

What i would like to be able to do is write something like:

let x = vec.iter().map(|x| x.iter()).filter(|x| x != naics);

The problem is.. I don't want to map across all of the elements per say, i just want to make across one column within the inner vec, which is column 31.

Sample Vec of Vec:

["471", "001020887", "", "1SNH0", "", "A", "Z2", "20020312", "20210711", "20200731", "20200731", "BENCHMARK INTERNATIONAL, INC", "", "", "", "5025 PIRATES COVE RD", "", "JACKSONVILLE", "FL", "32210", "8309", "USA", "04", "19990208", "1231", "http://www.bmiint.com", "2L", "VA", "USA", "0005", "27~2X~A5~QF~XS", "541611", "", "0002", "541611Y~541690Y", "0000", "", "N", "", "5025 PIRATES COVE RD", "", "JACKSONVILLE", "32210", "8309", "USA", "FL", "ANNA", "", "MCKENZIE", "", "5025 PIRATES COVE RD", "", "JACKSONVILLE", "32210", "8309", "USA", "FL", "4437170460", "", "", "", "[email protected]"], ["472", "001021310", "", "94867", "", "A", "Z2", "19980424", "20210323", "20200323", "20200323", "CHURCHILL CORPORATION", "", "", "", "344 FRANKLIN ST", "", "MELROSE", "MA", "02176", "1825", "USA", "05", "19480101", "0731", "", "2L", "MA", "USA", "0002", "2X~MF", "332322", "", "0001", "332322Y", "0000", "", "Y", "", "P.O.BOX 761038", "", "MELROSE", "02176", "1825", "USA", "MA", "MARSHALL", "W", "SCHERMERHORN", "", "P.O. BOX 761038", "344 FRANKLIN STREET", "MELROSE", "02176", "", "USA", "MA", "7816654700", "", "", "7816625291", "[email protected]"]]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不再见 2025-01-16 23:12:56

首先,确认我没有忽略某些事情:

您的代码等于

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    let mut return_vec_truncated = vec![];
    let mut return_vec_full = vec![];
    for i in vec.iter() {
        for naic in naics.iter() {
            if i[31] == *naic {
                return_vec_truncated.push(info_wanted(&i));
                return_vec_full.push(i.clone());
            }
        }
    }
    (return_vec_full, return_vec_truncated)
}

并且 contains_naice 是不必要的?除了 contains_naice 之外,我认为您的代码易于阅读并且很惯用。

如果你绝对想用迭代器编写它,你可以使用 flat_mapunzip

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    vec.iter()
        .flat_map(|i| naics.iter().filter(|naic| i[31] == **naic).map(move |_| i))
        .map(|i| (i.clone(), info_wanted(&i)))
        .unzip()
}

虽然我确实想知道:这真的是你想要的吗?您真的想要每个匹配的 naic 一份 i 副本吗?或者,如果任何 naics 匹配,您是否需要一份 i 副本?

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    vec.iter()
        .filter(|i| naics.iter().any(|naic| i[31] == *naic))
        .map(|i| (i.clone(), info_wanted(&i)))
        .unzip()
}

(相同的迭代代码将在 if 内有一个 break。)

First, to confirm that I'm not overlooking something:

Your code is equal to

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    let mut return_vec_truncated = vec![];
    let mut return_vec_full = vec![];
    for i in vec.iter() {
        for naic in naics.iter() {
            if i[31] == *naic {
                return_vec_truncated.push(info_wanted(&i));
                return_vec_full.push(i.clone());
            }
        }
    }
    (return_vec_full, return_vec_truncated)
}

and the contains_naice is unnecessary? Except for contains_naice, I think your code easy to read and plenty idiomatic.

If you absolutely want to write it with iterators, you can use flat_map and unzip:

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    vec.iter()
        .flat_map(|i| naics.iter().filter(|naic| i[31] == **naic).map(move |_| i))
        .map(|i| (i.clone(), info_wanted(&i)))
        .unzip()
}

Though I do wonder: Is that actually what you wanted? Do you really want one copy of i per matching naic? Or do you maybe want one copy of i if any of the naics match?

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    vec.iter()
        .filter(|i| naics.iter().any(|naic| i[31] == *naic))
        .map(|i| (i.clone(), info_wanted(&i)))
        .unzip()
}

(The equal iterative code would have a break inside the if.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文