英文:
How to sort a vector of strings by char in Rust?
问题
The more idiomatic way to sort a vector of strings by char in Rust is to use the sort_by
method with a custom comparator. Here's how you can achieve the desired output:
let mut vec = vec!["3r", "2n", "2s", "7r", "1s", "1s", "6r", "1s", "1n", "1n", "5n", "9n", "3r"];
vec.sort_by(|a, b| {
let (a1, a2) = a.chars().collect::<Vec<_>>().split_at(1);
let (b1, b2) = b.chars().collect::<Vec<_>>().split_at(1);
a2.cmp(b2).then(a1.cmp(b1))
});
println!("{:?}", vec);
This code will sort the vector first by the second character of each string and then by the first character, giving you the desired output.
英文:
What is the more idiomatic way to sort a vector of strings by char?
Example:
Input:
["3r", "2n", "2s", "7r", "1s", "1s", "6r", "1s", "1n", "1n", "5n", "9n", "3r"]
Desired output:
["1n", "1n", "2n", "5n", "9n, "3r", "3r", "6r", "7r", "1s", "1s", "1s", "2s"]
First they need to be sorted on the second char so they are grouped together, after that sorted by first char.
I tried a bunch of things with .filter
and .sort_by
but was not successful.
答案1
得分: 3
你可以通过迭代器访问字符串中的字符:
#[test]
fn sort_by_second_char() {
let mut input = [
"3r", "2n", "2s", "7r", "1s", "1s", "6r", "1s", "1n", "1n", "5n", "9n", "3r",
];
let output = [
"1n", "1n", "2n", "5n", "9n", "3r", "3r", "6r", "7r", "1s", "1s", "1s", "2s",
];
// this does not break even if the input string is of invalid format, if
// you are sure they are valid you can unwrap.
fn get_second_char(s: &&str) -> (Option<char>, Option<char>) {
let mut chars = s.chars();
let [num, char] = [chars.next(), chars.next()];
(char, num)
}
input.sort_by_key(get_second_char);
assert_eq!(input, output);
}
注意,如果元组的各个元素实现了Ord
,则元组本身也会实现Ord
。Option
如果包装的类型实现了Ord
(char
),那么Option
也会实现Ord
。
英文:
you can access chars in a string trough an iterator:
#[test]
fn sort_by_second_char() {
let mut input = [
"3r", "2n", "2s", "7r", "1s", "1s", "6r", "1s", "1n", "1n", "5n", "9n", "3r",
];
let output = [
"1n", "1n", "2n", "5n", "9n", "3r", "3r", "6r", "7r", "1s", "1s", "1s", "2s",
];
// this does not break even if the input string is of invalid format, if
// you are sure they are valid you can unwrap.
fn get_second_char(s: &&str) -> (Option<char>, Option<char>) {
let mut chars = s.chars();
let [num, char] = [chars.next(), chars.next()];
(char, num)
}
input.sort_by_key(get_second_char);
assert_eq!(input, output);
}
Note that tuples implement Ord
if their respective elements implement Ord
Option implements Ord
if type it wraps implements Ord
(char
)
答案2
得分: 2
If your strings are always two characters long, and you always want to sort them by the second character first, you can use .sort_by
with a comparator which looks at the strings in reverse:
let mut input = vec!("3r", "2n", "2s", "7r", "1s", "1s", "6r", "1s", "1n", "1n", "5n", "9n", "3r");
input.sort_by(|a, b| a.chars().rev().cmp(b.chars().rev()));
let expected = vec!("1n", "1n", "2n", "5n", "9n", "3r", "3r", "6r", "7r", "1s", "1s", "1s", "2s");
assert!(input == expected);
英文:
If your strings are always two characters long, and you always want to sort them by the second character first, you can use .sort_by
with a comparator which looks at the strings in reverse:
let mut input = vec!("3r", "2n", "2s", "7r", "1s", "1s", "6r", "1s", "1n", "1n", "5n", "9n", "3r");
input.sort_by(|a, b| a.chars().rev().cmp(b.chars().rev()));
let expected = vec!("1n", "1n", "2n", "5n", "9n", "3r", "3r", "6r", "7r", "1s", "1s", "1s", "2s");
assert!(input == expected);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论