История изменений
Исправление red75prim, (текущая версия) :
Не буду убеждать в красоте кода. Но сразу видно, что код - кривоватый: лайфтайм 'a
используется только в одном месте. Тот, кто писал, не совсем понимал, что делает.
Ну и можно написать немного понятнее. А так это - обычный функциональный pipeline.
pub fn closest_but_not_really<T>(
choice: &str,
iter: impl Iterator<Item = T>,
key: impl Fn(&T) -> &str,
) -> Option<T> {
iter.map(|item| {
let distance = lev_distance(choice, key(&item));
(distance, item)
})
.min_by_key(|&(distance, _)| distance)
.and_then(|(distance, item)| {
if distance < 4 {
Some(item)
} else {
None
}
})
}
Или можно написать в императивном стиле. Но тут больше возможностей сделать ошибку.
pub fn closest_less<T>(
choice: &str,
mut iter: impl Iterator<Item = T>,
key: impl Fn(&T) -> &str,
) -> Option<T> {
let mut min_item = iter.next()?;
let mut min_dist = lev_distance(choice, key(&min_item));
for item in iter {
let dist = lev_distance(choice, key(&item));
if dist < min_dist {
min_dist = dist;
min_item = item;
}
}
if min_dist < 4 {
Some(min_item)
} else {
None
}
}
Исправление red75prim, :
Не буду убеждать в красоте кода. Но сразу видно, что код - кривоватый: лайфтайм 'a
используется только в одном месте. Тот, кто писал, не совсем понимал, что делает.
Ну и можно написать немного понятнее. А так это - обычный функциональный pipeline.
pub fn closest_but_not_really<T>(
choice: &str,
iter: impl Iterator<Item = T>,
key: impl Fn(&T) -> &str,
) -> Option<T> {
iter.filter_map(|item| {
let distance = lev_distance(choice, key(&item));
if distance < 4 {
Some((distance, item))
} else {
None
}
})
.min_by_key(|&(distance, _)| distance)
.map(|(_, item)| item)
}
Или можно написать в императивном стиле. Но тут больше возможностей сделать ошибку.
pub fn closest_less<T>(
choice: &str,
mut iter: impl Iterator<Item = T>,
key: impl Fn(&T) -> &str,
) -> Option<T> {
let mut min_item = iter.next()?;
let mut min_dist = lev_distance(choice, key(&min_item));
for item in iter {
let dist = lev_distance(choice, key(&item));
if dist < min_dist {
min_dist = dist;
min_item = item;
}
}
if min_dist < 4 {
Some(min_item)
} else {
None
}
}
Исходная версия red75prim, :
Не буду убеждать в красоте кода. Но сразу видно, что код - кривоватый: лайфтайм 'a
используется только в одном месте. Тот, кто писал не совсем понимал, что делает.
Ну и можно написать немного понятнее. А так это - обычный функциональный pipeline.
pub fn closest_but_not_really<T>(
choice: &str,
iter: impl Iterator<Item = T>,
key: impl Fn(&T) -> &str,
) -> Option<T> {
iter.filter_map(|item| {
let distance = lev_distance(choice, key(&item));
if distance < 4 {
Some((distance, item))
} else {
None
}
})
.min_by_key(|&(distance, _)| distance)
.map(|(_, item)| item)
}
Или можно написать в императивном стиле. Но тут больше возможностей сделать ошибку.
pub fn closest_less<T>(
choice: &str,
mut iter: impl Iterator<Item = T>,
key: impl Fn(&T) -> &str,
) -> Option<T> {
let mut min_item = iter.next()?;
let mut min_dist = lev_distance(choice, key(&min_item));
for item in iter {
let dist = lev_distance(choice, key(&item));
if dist < min_dist {
min_dist = dist;
min_item = item;
}
}
if min_dist < 4 {
Some(min_item)
} else {
None
}
}