Last active
August 29, 2015 14:13
-
-
Save worthmine/f44b49e9806c767ca679 to your computer and use it in GitHub Desktop.
[Swift]extensionで実装するPerl風の配列操作 ref: http://qiita.com/worthmine/items/40bfdd8f1f75bfe3463a
This file contains 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 { | |
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 | |
} | |
} | |
} |
This file contains 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
// 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 |
This file contains 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
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 |
This file contains 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
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' |
This file contains 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
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