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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
# array_tool
[![Build Status](https://travis-ci.org/danielpclark/array_tool.svg?branch=master)](https://travis-ci.org/danielpclark/array_tool)
[![Build Status](https://ci.appveyor.com/api/projects/status/dffq3dwb8w220q4f/branch/master?svg=true)](https://ci.appveyor.com/project/danielpclark/array-tool/branch/master)
[![Documentation](https://img.shields.io/badge/docs-100%25-brightgreen.svg)](http://danielpclark.github.io/array_tool/index.html)
[![crates.io version](https://img.shields.io/crates/v/array_tool.svg)](https://crates.io/crates/array_tool)
[![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)]()
Array helpers for Rust. Some of the most common methods you would
use on Arrays made available on Vectors. Polymorphic implementations
for handling most of your use cases.
### Installation
Add the following to your Cargo.toml file
```toml
[dependencies]
array_tool = "1.0.0"
```
And in your rust files where you plan to use it put this at the top
```rust
extern crate array_tool;
```
And if you plan to use all of the Vector helper methods available you may do
```rust
use array_tool::vec::*;
```
This crate has helpful methods for strings as well.
## Iterator Usage
```rust
use array_tool::iter::ZipOpt;
fn zip_option<U: Iterator>(self, other: U) -> ZipOption<Self, U>
where Self: Sized, U: IntoIterator;
// let a = vec![1];
// let b = vec![];
// a.zip_option(b).next() // input
// Some((Some(1), None)) // return value
```
## Vector Usage
```rust
pub fn uniques<T: PartialEq + Clone>(a: Vec<T>, b: Vec<T>) -> Vec<Vec<T>>
// array_tool::uniques(vec![1,2,3,4,5], vec![2,5,6,7,8]) // input
// vec![vec![1,3,4], vec![6,7,8]] // return value
use array_tool::vec::Uniq;
fn uniq(&self, other: Vec<T>) -> Vec<T>;
// vec![1,2,3,4,5,6].uniq( vec![1,2,5,7,9] ) // input
// vec![3,4,6] // return value
fn uniq_via<F: Fn(&T, &T) -> bool>(&self, other: Self, f: F) -> Self;
// vec![1,2,3,4,5,6].uniq_via( vec![1,2,5,7,9], |&l, r| l == r + 2 ) // input
// vec![1,2,4,6] // return value
fn unique(&self) -> Vec<T>;
// vec![1,2,1,3,2,3,4,5,6].unique() // input
// vec![1,2,3,4,5,6] // return value
fn unique_via<F: Fn(&T, &T) -> bool>(&self, f: F) -> Self;
// vec![1.0,2.0,1.4,3.3,2.1,3.5,4.6,5.2,6.2].
// unique_via( |l: &f64, r: &f64| l.floor() == r.floor() ) // input
// vec![1.0,2.0,3.3,4.6,5.2,6.2] // return value
fn is_unique(&self) -> bool;
// vec![1,2,1,3,4,3,4,5,6].is_unique() // input
// false // return value
// vec![1,2,3,4,5,6].is_unique() // input
// true // return value
use array_tool::vec::Shift;
fn unshift(&mut self, other: T); // no return value, modifies &mut self directly
// let mut x = vec![1,2,3];
// x.unshift(0);
// assert_eq!(x, vec![0,1,2,3]);
fn shift(&mut self) -> Option<T>;
// let mut x = vec![0,1,2,3];
// assert_eq!(x.shift(), Some(0));
// assert_eq!(x, vec![1,2,3]);
use array_tool::vec::Intersect;
fn intersect(&self, other: Vec<T>) -> Vec<T>;
// vec![1,1,3,5].intersect(vec![1,2,3]) // input
// vec![1,3] // return value
fn intersect_if<F: Fn(&T, &T) -> bool>(&self, other: Vec<T>, validator: F) -> Vec<T>;
// vec!['a','a','c','e'].intersect_if(vec!['A','B','C'], |l, r| l.eq_ignore_ascii_case(r)) // input
// vec!['a','c'] // return value
use array_tool::vec::Join;
fn join(&self, joiner: &'static str) -> String;
// vec![1,2,3].join(",") // input
// "1,2,3" // return value
use array_tool::vec::Times;
fn times(&self, qty: i32) -> Vec<T>;
// vec![1,2,3].times(3) // input
// vec![1,2,3,1,2,3,1,2,3] // return value
use array_tool::vec::Union;
fn union(&self, other: Vec<T>) -> Vec<T>;
// vec!["a","b","c"].union(vec!["c","d","a"]) // input
// vec![ "a", "b", "c", "d" ] // return value
```
## String Usage
```rust
use array_tool::string::ToGraphemeBytesIter;
fn grapheme_bytes_iter(&'a self) -> GraphemeBytesIter<'a>;
// let string = "a s—d féZ";
// let mut graphemes = string.grapheme_bytes_iter()
// graphemes.skip(3).next(); // input
// [226, 128, 148] // return value for emdash `—`
use array_tool::string::Squeeze;
fn squeeze(&self, targets: &'static str) -> String;
// "yellow moon".squeeze("") // input
// "yelow mon" // return value
// " now is the".squeeze(" ") // input
// " now is the" // return value
use array_tool::string::Justify;
fn justify_line(&self, width: usize) -> String;
// "asd as df asd".justify_line(16) // input
// "asd as df asd" // return value
// "asd as df asd".justify_line(18) // input
// "asd as df asd" // return value
use array_tool::string::SubstMarks;
fn subst_marks(&self, marks: Vec<usize>, chr: &'static str) -> String;
// "asdf asdf asdf".subst_marks(vec![0,5,8], "Z") // input
// "Zsdf ZsdZ asdf" // return value
use array_tool::string::WordWrap;
fn word_wrap(&self, width: usize) -> String;
// "01234 67 9 BC EFG IJ".word_wrap(6) // input
// "01234\n67 9\nBC\nEFG IJ" // return value
use array_tool::string::AfterWhitespace;
fn seek_end_of_whitespace(&self, offset: usize) -> Option<usize>;
// "asdf asdf asdf".seek_end_of_whitespace(6) // input
// Some(9) // return value
// "asdf".seek_end_of_whitespace(3) // input
// Some(0) // return value
// "asdf ".seek_end_of_whitespace(6) // input
// None // return_value
```
## Future plans
Expect methods to become more polymorphic over time (same method implemented
for similar & compatible types). I plan to implement many of the methods
available for Arrays in higher languages; such as Ruby. Expect regular updates.
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([MIT-LICENSE](MIT-LICENSE) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
|