Skip to content

Instantly share code, notes, and snippets.

@worthmine
Last active August 29, 2015 14:13
Show Gist options
  • Save worthmine/f44b49e9806c767ca679 to your computer and use it in GitHub Desktop.
Save worthmine/f44b49e9806c767ca679 to your computer and use it in GitHub Desktop.
[Swift]extensionで実装するPerl風の配列操作 ref: http://qiita.com/worthmine/items/40bfdd8f1f75bfe3463a
extension Array {
typealias Element = T
mutating func scalar() -> Int { // use it if you like perl
return Int(self.count)
}
mutating func pop() -> T? {
return self.isEmpty ? nil : self.removeAtIndex(self.endIndex.predecessor())
}
mutating func push(newElements: T...) -> [T] {
self.splice(newElements, atIndex: self.endIndex)
return self
}
mutating func shift() -> T? {
return self.isEmpty ? nil : self.removeAtIndex(self.startIndex)
}
mutating func unshift(elements: T...) -> [T] {
self.splice(elements, atIndex: self.startIndex)
return self
}
mutating func splice(var _ atIndex :Int = 0, _ length :Int = 0, _ newElements: T...) -> Slice<T>? {
description
var theIndex = length + atIndex
var spliced :Slice<T> = []
if length < 0 {fatalError("minus length was set")}
if atIndex >= 0 {
if theIndex > self.endIndex {fatalError("Bad Access")}
let preArray = atIndex > 0 ? self[self.startIndex..<atIndex] : []
spliced = length > 0 ? self[atIndex..<theIndex] : []
let postArray = self[theIndex..<self.endIndex]
self = preArray + Array(newElements) + postArray
return length > 0 ? Slice(spliced) : nil
} else { // you can use minus atIndex because it is like Perl
let reversed = self.reverse()
atIndex = abs(atIndex + 1)
theIndex = length + atIndex
if theIndex > self.endIndex {fatalError("Bad Access")}
let postArray = atIndex > 0 ? reversed[reversed.startIndex..<atIndex].reverse() : []
spliced = length > 0 ? reversed[atIndex..<theIndex].reverse() : []
let preArray = theIndex < reversed.endIndex ? reversed[theIndex..<reversed.endIndex].reverse() :[]
self = preArray + Array(newElements) + postArray
return length > 0 ? Slice(spliced) : nil
}
}
}
// Use like bellow
var a :Array = ["Four", "Seven", "Eight" ]
a.splice(["Five", "Six"], atIndex: 1) // using a default splice
a.splice(2, 0, "Five2" ) // -> nil //use splice with no adding. it returns nil but sucsesses to splice
a.splice(2, 2, "Six3", "Seven2") // -> {["Five2", "Six"]} // using mutating splice
a.splice(-4, 1, "Six4" ) // -> {["Six3"]} // use a added splice
a // -> ["Four", "Five", "Six4", "Seven2", "Eight"]
a.splice(0, a.count, "other", "Strings", "like", "those")
a // -> ["other", "Strings", "like", "those"]
a.splice(-2, 2) // -> ["Strings", "like"]
a = ["Four", "Five", "Six", "Seven", "Eight" ]
a.unshift("Two", "Three") // insert an array to the top of this Array
a.unshift("One") // add a value to the top of this Array
a.count // -> 8
a.push("Nine", "Ten") // add an array to the bottom of this Array
a.push("Eleven") // add a value to the bottom of this Array
a[2] // -> "Three"
a[2...3] // -> "Three", "Four"
a // -> ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven"]
a.count // -> 11
a.shift() // remove one value from the top of this Array
a.pop() // remove one value from the bottom of this Array
a.count // -> 9
// for Int
var b :Array = [4, 7, 8 ] // -> [4,7,8]
b.count // -> 3
b.splice([5, 6], atIndex: 1) // -> [4,5,6,7,8]
b.unshift(2, 3)[0...0] // -> [2]
var unshifted = b.unshift(1) // -> [1,2,3,4,5,6,7,8]
unshifted.unshift(0) // -> [0,1,2,3,4,5,6,7,8]
b // -> [1,2,3,4,5,6,7,8]
b.push(9, 10)[1...3] // -> [2,3,4]
b.push(11)[b.startIndex] // -> 1
b[2] // -> 3
b.shift() // -> {Some 1} // because the Type has been never defined
var shifted = b.shift()! // -> 2 // it must be bad at grammar because pop and shift may return nil
b.splice(0, b.count-2) // splice 7 elements with no adding it's the very Perl-like!
var popped :Int! = b.pop() // -> 11 // it will be a better way
popped = b.pop() as Int? // -> 10 // how to down cast
b.count // -> 0 // it means this Array is Empty
popped = b.pop() as Int? // -> nil //pop and shift will return nil if there is no value
var b :Array = [4, 7, 8 ] // -> [4, 7, 8]
b.count // -> 3
//のとき、
b.push(9, 10)[1...3] // -> [7, 8, 9]
b.push(11)[b.endIndex.predecessor()] // -> 11
var forNil = [nil, nil, nil] // Cannot convert the expression's type 'Array' to type 'NilLiteralConvertible'
a.unshift(nil) // Type '(String...)' does not conform to protocol 'NilLiteralConvertible'
b.unshift(nil,nil) // Type 'Int' does not conform to protocol 'NilLiteralConvertible'
b.splice(0, 0, nil) // Type 'Int' does not conform to protocol 'NilLiteralConvertible'
var forNil = [nil, nil, nil] // Cannot convert the expression's type 'Array' to type 'NilLiteralConvertible'
a.unshift(nil) // Type '(String...)' does not conform to protocol 'NilLiteralConvertible'
b.unshift(nil,nil) // Type 'Int' does not conform to protocol 'NilLiteralConvertible'
b.splice(0, 0, nil) // Type 'Int' does not conform to protocol 'NilLiteralConvertible'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment