1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use crate::arrays::array::Array;
use crate::base::base_array::ArrayBase;
use crate::base::base_type::Numeric;
impl <N: Numeric> std::fmt::Display for Array<N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if f.alternate() {
write!(f, "{}", build_string(self, true))
} else {
write!(f, "{}", build_string(self, false))
}
}
}
pub trait ArrayDisplay<N: Numeric> {}
impl <N: Numeric> ArrayDisplay<N> for Array<N> {}
fn build_string<N: Numeric>(arr: &Array<N>, pretty: bool) -> String {
if arr.is_empty() {
return "[]".to_string();
} else if arr.len() == 1 {
return format!("[{}]", arr.elements[0]);
}
let multiply = arr.shape.iter().enumerate()
.map(|(idx, _)| arr.shape[0..=idx].iter().product())
.collect::<Vec<usize>>();
let mut str = vec!["[".repeat(multiply.len())];
arr.elements.iter().enumerate().for_each(|(idx, &elem)| {
if idx == 0 && arr.shape[arr.ndim() - 1] != 1 {
str.push(format!("{elem}, "));
} else if idx == 0 {
str.push(format!("{elem}"));
} else {
let separators = multiply.iter()
.filter(|&s| idx % s == 0)
.count();
str.push("]".repeat(separators));
if separators > 0 {
str.push(", ".to_string());
if pretty {
str.push("\n".to_string());
str.push(" ".repeat(arr.shape.len() - separators));
}
}
str.push("[".repeat(separators));
if idx % arr.shape[0] != arr.shape[0] - 1 {
str.push(format!("{elem}, "));
} else {
str.push(format!("{elem}"));
}
}
});
multiply.iter().for_each(|_| str.push("]".to_string()));
str.join("")
}