I have a line of vertice, and want to try coupling it with another line of vertice.
Line 1: [1, 10, 20, 5]
Line 2: [1, 2, 3]
expected output:
Line 3: [3, 2, 1, 10, 20, 5] (or reversed order, doesn't matter)
In the code I have to check 4 ways the lines can match. For example, lines with vertice [1, 2]
and [2, 3]
can appear like these:
[1, 2], [2, 3]
[1, 2], [3, 2] # need to reverse left or right
[2, 1], [2, 3] # need to reverse left or right
[2, 1], [3, 2]
The output should be [1, 2, 3]
or [3, 2, 1]
.
Here's the code I could finally wrote. (In the real app, Line
has other attributes, but for simplicity I omit them here.)
#[derive(Clone)]
struct Line {
vertice: Vec<i64>
}
impl Line {
fn ends(&self) -> [i64; 2] {
[self.vertice[0].clone(), self.vertice[self.vertice.len() - 1].clone()]
}
fn couple(&self, other: &Line) -> Option<Line> {
let new_vertice:Vec<i64> = {
let se = self.ends();
let oe = other.ends();
let mine = &self.vertice;
let their = &other.vertice;
if se[0] == oe[0] {
mine[1..].iter().rev().into_iter().chain(their.iter()).cloned().collect()
} else if se[0] == oe[1] {
their.iter().chain(mine[1..].iter()).cloned().collect()
} else if se[1] == oe[0] {
mine.iter().chain(their[1..].iter()).cloned().collect()
} else if se[1] == oe[1] {
mine[..mine.len() - 1].iter().chain(their.iter().rev()).cloned().collect()
} else {
return None;
}
};
Some(Line { vertice: new_vertice })
}
}
I tried abstracting the code to reduce the repetitions of chain
/cloned
/collect
calls, but it turned out even worse. A function can't accept Iterator
/Rev<X>
, only one of this kind, and I couldn't wrap them together. If instead I make a function accepting Vec
, I need to call iter/cloned/collect to make a Vec before it.
fn couple2(a: &Vec<i64>, b: &Vec<i64>) -> Vec<i64> {
a.iter().chain(b.iter()).cloned().collect()
}
...
if se[0] == oe[0] {
couple2(&mine[1..].iter().rev().cloned().collect(), their)
} else if se[0] == oe[1] {
couple2(their, &mine[1..].iter().cloned().collect())
} else if se[1] == oe[0] {
couple2(mine, &their[1..].iter().cloned().collect())
} else if se[1] == oe[1] {
couple2(&mine[..mine.len() - 1].iter().cloned().collect(), &their.iter().rev().cloned().collect())
...
Did I miss some more ideomatic way to do this?