rust


How to call count on an iterator and still use the iterator's items?


parts.count() leads to ownership transfer, so parts can't be used any more.
fn split(slice: &[u8], splitter: &[u8]) -> Option<Vec<u8>> {
let mut parts = slice.split(|b| splitter.contains(b));
let len = parts.count(); //ownership transfer
if len >= 2 {
Some(parts.nth(1).unwrap().to_vec())
} else if len >= 1 {
Some(parts.nth(0).unwrap().to_vec())
} else {
None
}
}
fn main() {
split(&[1u8, 2u8, 3u8], &[2u8]);
}
It is also possible to avoid unnecessary allocations of Vec if you only need to use the first or the second part:
fn split<'a>(slice: &'a [u8], splitter: &[u8]) -> Option<&'a [u8]> {
let mut parts = slice.split(|b| splitter.contains(b)).fuse();
let first = parts.next();
let second = parts.next();
second.or(first)
}
Then if you actually need a Vec you can map on the result:
split(&[1u8, 2u8, 3u8], &[2u8]).map(|s| s.to_vec())
Of course, if you want, you can move to_vec() conversion to the function:
second.or(first).map(|s| s.to_vec())
I'm calling fuse() on the iterator in order to guarantee that it will always return None after the first None is returned (which is not guaranteed by the general iterator protocol).
The other answers are good suggestions to answer your problem, but I'd like to point out another general solution: create multiple iterators:
fn split(slice: &[u8], splitter: &[u8]) -> Option<Vec<u8>> {
let mut parts = slice.split(|b| splitter.contains(b));
let parts2 = slice.split(|b| splitter.contains(b));
let len = parts2.count();
if len >= 2 {
Some(parts.nth(1).unwrap().to_vec())
} else if len >= 1 {
Some(parts.nth(0).unwrap().to_vec())
} else {
None
}
}
fn main() {
split(&[1u8, 2u8, 3u8], &[2u8]);
}
You can usually create multiple read-only iterators. Some iterators even implement Clone, so you could just say iter.clone().count(). Unfortunately, Split isn't one of them because it owns the passed-in closure.
One thing you can do is collect the results of the split in a new owned Vec, like this:
fn split(slice: &[u8], splitter: &[u8]) -> Option<Vec<u8>> {
let parts: Vec<&[u8]> = slice.split(|b| splitter.contains(b)).collect();
let len = parts.len();
if len >= 2 {
Some(parts.iter().nth(1).unwrap().to_vec())
} else if len >= 1 {
Some(parts.iter().nth(0).unwrap().to_vec())
} else {
None
}
}

Related Links

What ways exist to create containers of several types? [duplicate]
How can I optimize reading a UTF-8 string from a file with a known offset and size?
Create vector of objects implementing a trait in Rust
Using loop variable from “..” loop causes type conversion?
What is RFC 401's coerce_inner useful for?
Rust Borrow checker only complains about borrowing as mutable multiple times when a function that returns a reference with the same lifetime assigned
How can I remove `let _ : () = …`?
Does if-let with a pair short-circuit?
Rust borrow lasts beyond the scope it's in?
How can I include an arbitrary set of Protobuf-built files without knowing their names?
Specialization of method in inherent impl
Getting reference to object behind Rc
Similar implementations of one trait for many structs
Unable to find unsafe trait implementation
Injecting a Diesel connection into an Iron middleware
Rust function does not have static lifetime?

Categories

HOME
generics
tomcat
mpdf
focus
exchange-server
applescript
initialization
visual-studio-2010
elisp
header
google-sheets-query
gentelella
anchor
gtk
lda
spring-amqp
reselect
android-5.1.1-lollipop
gmp
cpu-usage
significance
kaggle
pymongo
quartz.net
function-points
introspection
ipa
uri
fstar
oracleforms
tortoisehg
boolean-logic
mongoengine
payeezy
xerces-c
love2d
ms-dos
1wire
expandablelistview
ipp-protocol
icecast
jgrapht
openstack-glance
exc-bad-access
mobile-angular-ui
swiperefreshlayout
word-2016
business-rules
oracle-fusion-apps
haraka
xmlbeans
mathjs
system.net.mail
piping
verisign
gwt-syncproxy
outlook.com
decidable
nette
dsa
screen-orientation
jnlp
sequence-sql
angular-amd
artisan
kefir.js
prism-4
nssortdescriptor
mutators
tkx
nhibernate-criteria
fat32
global-scope
loginview
incognito-mode
cpu-time
pre
armv6
django-facebook
microformats
dibs
semicolon
system-requirements
idispatch
voice-recording
image-scanner
jzmq
platform-independent
django-apps
motodev-studio
data-dump
office-automation
3des
gaelyk
mysqli-multi-query
accumulator
suggestbox
server-load
code-camp

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App