This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| extension Array { | |
| func mapParallel<T>(transform: @escaping (Element) -> T ) -> [T] { | |
| let n = self.count | |
| let temp = UnsafeMutablePointer<T>.allocate(capacity: n) | |
| let dg = DispatchGroup() | |
| DispatchQueue.concurrentPerform(iterations: n) { i in | |
| dg.enter() | |
| temp[i] = transform(self[i]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // implemented according to this answer | |
| // https://stackoverflow.com/a/24755958/6641096 | |
| func measureInMilliseconds(_ block: () -> ()) -> UInt64 { | |
| let start = DispatchTime.now() | |
| block() | |
| let end = DispatchTime.now() | |
| // Difference in nano seconds (UInt64) | |
| let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func callBlocking<T>( | |
| _ closure: @escaping (_ continuationHandler: @escaping (T) -> Void ) -> Void ) | |
| -> T { | |
| let dispatchGroup = DispatchGroup() | |
| dispatchGroup.enter() | |
| var result:T? = nil | |
| closure { res in | |
| result = res | |
| dispatchGroup.leave() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// It joins words grammatically e.g. ["apple", "orange", "banana"] -> "apple, orange and banana" | |
| /// and parameter is required to support different languages | |
| func joinGrammatically(words: [String], and: String) -> String { | |
| if words.count == 0 { | |
| return "" | |
| } | |
| else if words.count == 1 { | |
| return words.first! | |
| } | |
| else { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # items must be sorted from best to worst | |
| def non_max_suppress(items_sorted, suppress_predicate): | |
| num_items = len(items_sorted) | |
| skip = [False]*num_items | |
| i = 0 | |
| while i < num_items: | |
| if skip[i]: | |
| i += 1 | |
| continue |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| _numeric_types = (int, float, complex) | |
| class NumericDict(dict): | |
| def __add__(self, other): | |
| if isinstance(other, _numeric_types): | |
| return self.apply(lambda v: v + other) | |
| if isinstance(other, NumericDict): | |
| return self.__class__({k: v + other.get(k, 0) for k, v in self.items()}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import functools | |
| def renewing(generator): | |
| """ | |
| A decorator to turn a generator into an object that can be | |
| iterated multiple times, restarting the generator each time. | |
| """ | |
| class RenewingGenerator: | |
| def __init__(self, *args, **kwargs): | |
| self.args = args |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class LiveChange<T>(val source: LiveData<T>, ignoreFirst: Boolean = false) : MediatorLiveData<T>() { | |
| private var shouldIgnoreNext: Boolean = ignoreFirst | |
| init { | |
| addSource(source) { | |
| if (shouldIgnoreNext) { | |
| shouldIgnoreNext = false | |
| } else { | |
| if (value != it) value = it | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def batch(iterable, size, drop_remainder=False): | |
| if size < 1: | |
| raise ValueError("size must be greater than zero.") | |
| iterator = iter(iterable) | |
| while True: | |
| try: | |
| items = [] | |
| for _ in range(size): | |
| items.append(next(iterator)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // https://stackoverflow.com/a/52075248/6641096 | |
| fun <T> MutableLiveData<T>.notifyObserver() { | |
| this.value = this.value | |
| } | |
| // Usage | |
| fun addSomething(item: Item) { | |
| listLiveData.value?.add(item) | |
| listLiveData.notifyObserver() |