Skip to content

Instantly share code, notes, and snippets.

@sketchytech
Last active August 29, 2015 14:05
Show Gist options
  • Save sketchytech/16c48bd381f4a20db61e to your computer and use it in GitHub Desktop.
Save sketchytech/16c48bd381f4a20db61e to your computer and use it in GitHub Desktop.
Swift Generic Functions (that work with String and Array instances)
// SORTED SET - removes duplicates and orders a sequence that adopts the ExtensibleCollectionType protocol
var arr = [1,22,22,34,3,3,5,6]
var arrStr = ["bee","ant","tree","ant","fox","rabbit","fox"]
sortedSet(arr) // returns [1,3,5,6,22,34]
sortedSet(arrStr) // returns ["ant","bee","fox","rabbit","tree"]
// INSERT - insert a sequence in a type that adopts RangeReplaceableCollectionType at an Index
var str = "Hello, playground"
var arr = [1,2,3,4,5,6,6,5,4,3]
insert(&arr, [1,2,3], 5)
insert(&str, "HI THERE!", 7)
// DELETE DUPLICATES in a type that adopts ExtensibleCollectionType
deleteDuplicates([1,2,2,3,2,4,5,6,6]) // returns [1,2,3,4,5,6]
deleteDuplicates("Hello, playground") // returns "Helo, paygrund"
// FINDS - find multiple Elements in a Collection
finds([1,2,3,4,4,5,5,6], 4) // returns [3,4]
finds("lllllllllll", "l") // returns [0,1,2,3,4,5,6,7,8,9,10]
finds(["one","two","one"], "one") // returns [0,2]
// Removed contains() and reduce() from function to make it less expensive
func sortedSet<S:CollectionType where S.Generator.Element: Comparable>(seq:S) -> [S.Generator.Element] {
var set = sorted(seq){$0<$1}
var inds = [Int]()
for s in enumerate(set) {
if s.index > 0 && s.element == set[advance(set.startIndex, s.index-1,set.endIndex)] {
inds.append(s.index-1)
}
}
for i in inds {
set.removeAtIndex(advance(set.startIndex, i, set.endIndex))
}
return set
}
// Old sortedSet function for reference only
/* func sortedSet<S: ExtensibleCollectionType where S.Generator.Element: Equatable>(seq:S)-> [S.Generator.Element] {
let s = reduce(seq, S()){
ac, x in contains(ac,x) ? ac : ac + [x]
}
let set = sorted(s){$0<$1}
return set
} */
// added splice(), pointed out by [@AirspeedSwift](http://twitter.com/AirspeedSwift)
func insert<S:RangeReplaceableCollectionType, I: SignedIntegerType where I == S.Index.Distance, S.Generator.Element: Equatable>(inout seq:S, ins:S, ind:I) {
// use of abs() prevents a negative value causing the insertIndex to be before the startIndex
var insertIndex = advance(seq.startIndex, abs(ind), seq.endIndex)
splice(&seq, ins, atIndex: insertIndex)
}
func deleteDuplicates<S:ExtensibleCollectionType where S.Generator.Element: Comparable>(seq:S)-> S {
let s = reduce(seq, S()){
ac, x in contains(ac,x) ? ac : ac + [x]
}
return s
}
func finds<C: CollectionType, E: Equatable where E == C.Generator.Element>(haystack:C, needle:E) -> [C.Index] {
var startInd = haystack.startIndex, arr = Array<C.Index>()
do {
if haystack[startInd] ==
needle
{
arr.append(startInd)
}
startInd = advance(startInd,1)
}
while startInd != haystack.endIndex
return arr
}
@sketchytech
Copy link
Author

Thank you to @AirspeedSwift for identifying that ExtensibleCollectionType should be used in place of RangeReplaceableCollectionType. Thanks to @ChromophoreApp for first explaining the reduce() method. And thanks as ever to @SwiftLDN for bringing us all together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment