Сохранить элементы сплит над [дубликат]

В настоящее время я вношу свой вклад в решение этой проблемы с открытым исходным кодом с помощью проекта MCViewFactory, который можно найти здесь:

https://github.com/YetiHQ/manticore-iosviewfactory

Идея имитирует парадигму намерений Android, используя глобальную фабрику для управления просмотром, на который вы смотрите, и используя «намерения» для переключения и передачи данных между представлениями. Вся документация находится на странице github, но вот некоторые основные моменты:

Вы настраиваете все свои представления в файлах .XIB и регистрируете их в делегате приложения при инициализации фабрики.

// Register activities

MCViewFactory *factory = [MCViewFactory sharedFactory];

// the following two lines are optional. 
[factory registerView:@"YourSectionViewController"]; 

Теперь, в вашем VC, в любое время, когда вы хотите перейти на новый VC и передать данные, вы создаете новое намерение и добавляете данные в свой словарь (savedInstanceState). Затем просто установите текущее намерение фабрики:

MCIntent* intent = [MCIntent intentWithSectionName:@"YourSectionViewController"];
[intent setAnimationStyle:UIViewAnimationOptionTransitionFlipFromLeft];
[[intent savedInstanceState] setObject:@"someValue" forKey:@"yourKey"];
[[intent savedInstanceState] setObject:@"anotherValue" forKey:@"anotherKey"];
// ...
[[MCViewModel sharedModel] setCurrentSection:intent];

. Все ваши представления, которые соответствуют этому, должны быть подклассами MCViewController, которые позволяют вам переопределить новый метод onResume:, позволяющий вам получить доступ к данные, которые вы прошли.

-(void)onResume:(MCIntent *)intent {
    NSObject* someValue = [intent.savedInstanceState objectForKey:@"yourKey"];
    NSObject* anotherValue = [intent.savedInstanceState objectForKey:@"anotherKey"];

    // ...

    // ensure the following line is called, especially for MCSectionViewController
    [super onResume:intent];
}

Надеюсь, что некоторые из вас считают это решение полезным / интересным.

9
задан Keho 28 August 2015 в 16:16
поделиться

2 ответа

Использование str::match_indices :

let text = "Ten. Million. Questions. Let's celebrate all we've done together.";

let mut result = Vec::new();
let mut last = 0;
for (index, matched) in text.match_indices(|c: char| !(c.is_alphanumeric() || c == '\'')) {
    if last != index {
        result.push(&text[last..index]);
    }
    result.push(matched);
    last = index + matched.len();
}
if last < text.len() {
    result.push(&text[last..]);
}

println!("{:?}", result);

Печать:

["Ten", ".", " ", "Million", ".", " ", "Questions", ".", " ", "Let\'s", " ", "celebrate", " ", "all", " ", "we\'ve", " ", "done", " ", "together", "."]

4
ответ дан robinst 25 August 2018 в 01:51
поделиться

Мне не удалось найти что-либо в стандартной библиотеке, поэтому я написал свой собственный :

. Эта версия использует нестабильный API-интерфейс, поскольку он более гибкий, но ссылка выше, имеет резерв, который я жестко запрограммировал для своей конкретной стабильной usecase.

#![feature(pattern)]

use std::str::pattern::{Pattern, Searcher};

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum SplitType<'a> {
    Match(&'a str),
    Delimiter(&'a str),
}

pub struct SplitKeepingDelimiter<'p, P>
where
    P: Pattern<'p>,
{
    searcher: P::Searcher,
    start: usize,
    saved: Option<usize>,
}

impl<'p, P> Iterator for SplitKeepingDelimiter<'p, P>
where
    P: Pattern<'p>,
{
    type Item = SplitType<'p>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.start == self.searcher.haystack().len() {
            return None;
        }

        if let Some(end_of_match) = self.saved.take() {
            let s = &self.searcher.haystack()[self.start..end_of_match];
            self.start = end_of_match;
            return Some(SplitType::Delimiter(s));
        }

        match self.searcher.next_match() {
            Some((start, end)) => {
                if self.start == start {
                    let s = &self.searcher.haystack()[start..end];
                    self.start = end;
                    Some(SplitType::Delimiter(s))
                } else {
                    let s = &self.searcher.haystack()[self.start..start];
                    self.start = start;
                    self.saved = Some(end);
                    Some(SplitType::Match(s))
                }
            }
            None => {
                let s = &self.searcher.haystack()[self.start..];
                self.start = self.searcher.haystack().len();
                Some(SplitType::Match(s))
            }
        }
    }
}

pub trait SplitKeepingDelimiterExt: ::std::ops::Index<::std::ops::RangeFull, Output = str> {
    fn split_keeping_delimiter<P>(&self, pattern: P) -> SplitKeepingDelimiter<P>
    where
        P: for<'a> Pattern<'a>,
    {
        SplitKeepingDelimiter {
            searcher: pattern.into_searcher(&self[..]),
            start: 0,
            saved: None,
        }
    }
}

impl SplitKeepingDelimiterExt for str {}

#[cfg(test)]
mod test {
    use super::SplitKeepingDelimiterExt;

    #[test]
    fn split_with_delimiter() {
        use super::SplitType::*;
        let delims = &[',', ';'][..];
        let items: Vec<_> = "alpha,beta;gamma".split_keeping_delimiter(delims).collect();
        assert_eq!(
            &items,
            &[
                Match("alpha"),
                Delimiter(","),
                Match("beta"),
                Delimiter(";"),
                Match("gamma")
            ]
        );
    }

    #[test]
    fn split_with_delimiter_allows_consecutive_delimiters() {
        use super::SplitType::*;
        let delims = &[',', ';'][..];
        let items: Vec<_> = ",;".split_keeping_delimiter(delims).collect();
        assert_eq!(&items, &[Delimiter(","), Delimiter(";")]);
    }
}

Вы заметите, что мне нужно было отслеживать, было ли что-то одним из разделителей или нет, но это должно быть легко адаптируйте, если вам это не нужно.

3
ответ дан Shepmaster 25 August 2018 в 01:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: