Does Swift have a function similar to numpy.diff that calculates the difference between adjacent elements of an array - swift

I'm trying to convert some Python code to Swift and wondering if there is an existing function to calculate the difference between successive elements in a Swift array. For example:
diff([1,3,5,6,10]) would return [2,2,1,4]

No, but it could be very easily implemented:
let a = [1, 3, 5, 6, 10]
zip(a.dropFirst(), a).map(-) // => [2, 2, 1, 4]
It's simple enough that it's probably not worth wrapping into a function, but if you insist:
extension Collection where Element: Numeric {
func diff() -> [Element] {
return zip(self.dropFirst(), self).map(-)
}
}
[1, 3, 5, 6, 10].diff() // => [2, 2, 1, 4]
If you need the result to be lazily evaluated, you can do this:
extension Collection where Element: Numeric {
func diff() -> AnyCollection<Element> {
return AnyCollection(zip(self.dropFirst(), self).lazy.map(-))
}
}

You can use reduce(into:) combined with dropfirst to achieve what you want:
extension Collection where Element: SignedNumeric {
func diff() -> [Element] {
guard var last = first else { return [] }
return dropFirst().reduce(into: []) {
$0.append($1 - last)
last = $1
}
}
}
Another option is to use map and defer:
extension Collection where Element: SignedNumeric {
func diff() -> [Element] {
guard var last = first else { return [] }
return dropFirst().map { element in
defer { last = element }
return element - last
}
}
}
let arr = [1,3,5,6,10]
print(arr.diff()) // "[2, 2, 1, 4]\n"

There's no built in function for this, but you can easily implement it recursively. Thanks for the HeadTail extension for #Alexander.
extension Array {
func headTail<ReturnType>(_ closure: (Element?, [Element]) -> ReturnType) -> ReturnType {
return closure(self.first, Array(self.dropFirst()))
}
}
extension Array where Element == Int {
func diff() -> [Int] {
return self.headTail { head, tail in
guard let head = head, let next = tail.first else { return [] } //base case, empty list
return [next - head] + tail.diff()
}
}
}

Related

Highest frequency element in the dictionary

I am trying to find the highest frequency element in the given as follows.
First, I am trying to build a dictionary and count the each element based on frequency.
I am stuck how to extract max value from the constructed dictionary.
Input: [3,2,3]
Output: 3
func majorityElement(_ nums1: [Int]) -> Int {
var num1Dict = Dictionary(nums1.map{ ($0, 1) }, uniquingKeysWith : +)
return num1Dict.values.max() // ????
}
You have correctly constructed num1Dict, which will be something like this for the input [3,2,3]:
[2:1, 3:2]
values.max() will return 2, because out of all the values in the dictionary (1 and 2), 2 is the highest.
See your error now?
You need to return the key associated with the highest value, not the highest value.
One very straightforward way is to do this:
func majorityElement(_ nums1: [Int]) -> Int? { // you should probably return an optional here in case nums1 is empty
let num1Dict = Dictionary(nums1.map{ ($0, 1) }, uniquingKeysWith : +)
var currentHigh = Int.min
var mostOccurence: Int?
for kvp in num1Dict {
if kvp.value > currentHigh {
mostOccurence = kvp.key
currentHigh = kvp.value
}
}
return mostOccurence
}
You can use reduce(into:) to generate a Dictionary with the elements and their frequencies, then sort your array using those frequencies, then simply return the last element (based on ascending ordering) of the sorted array.
extension Array where Element: Comparable & Hashable {
func sortByNumberOfOccurences() -> [Element] {
let occurencesDict = self.reduce(into: [Element:Int](), { currentResult, element in
currentResult[element, default: 0] += 1
})
return self.sorted(by: { current, next in occurencesDict[current]! < occurencesDict[next]!})
}
func elementWithHighestFrequency() -> Element? {
return sortByNumberOfOccurences().last
}
}
Disclaimer: the sortByNumberOfOccurences method is copied from another answer of mine.
The mathematical name for what you're looking for (the most frequent element in a collection) is called the mode. There could be ties (e.g. [1, 1, 2, 2, 3, 3] has 3 modes: [1, 2, 3])
If you want any one of the modes (not caring which ones, specifically), you can use Dictionary.max(by:), which you can use to find the (element, count) pair with the highest count (which is the dict value). Then, you can get the key of this pair, which will be the mode element.
extension Sequence where Element: Hashable {
func countOccurrences() -> [Element: Int] {
return self.reduce(into: [:]) { (occurences, element) in occurences[element, default: 0] += 1}
}
func mode() -> Element? {
return self.countOccurrences()
.max(by: { $0.value < $1.value })?
.key
}
func modes() -> [Element] {
var firstModeNumOccurences: Int? = nil
let modes = countOccurrences()
.sorted { pairA, pairB in pairA.value > pairB.value } // sorting in descending order of num occurences
.lazy
.prefix(while:) { (_, numOccurences) in
if firstModeNumOccurences == nil { firstModeNumOccurences = numOccurences }
return numOccurences == firstModeNumOccurences
}
.map { (element, _) in element }
return Array(modes)
}
}
print([1, 2, 3, 3, 4, 4].mode() as Any) // => 3 or 4, non-deterministic
print([1, 2, 3, 3, 4, 4].modes() as Any) // => [3, 4]

Swift method on generic 2 dimensional Array

I would like to create an extension method on the Array type when the array is a 2 dimensional array, ex. [[Int]], but the type should be generic. I'm trying to do something like this:
extension Array [where Element : ???] {
public func transposed() -> ??? {
// ...
}
}
This worked in Swift 4.
extension Array where Element: Collection {
public func transposed() -> [[Element.Iterator.Element]] {
var result : [[Element.Iterator.Element]] = [[]]
for row in self {
for (y,column) in row.enumerated() {
while (result.count <= y) {
result.append([])
}
result[y].append(column)
}
}
return result
}
}
Then also unit testing passed:
func testTransposed() {
XCTAssertEqual([[1]].transposed(), [[1]])
XCTAssertEqual([[1,2,3],[4,5]].transposed(), [[1,4],[2,5],[3]])
XCTAssertEqual([[4,1],[5,2],[3]].transposed(),[[4,5,3],[1,2]])
XCTAssertEqual([[1,2,3]].transposed(), [[1],[2],[3]])
XCTAssertEqual([[1],[2],[3]].transposed(),[[1,2,3]])
}
You could do this:
extension Array
{
func transposed<T>() -> [[T]] where Element == Array<T>
{
return self[0].indices.map{ i in self.map{$0[i]} }
}
}
let a = [ [1,2,3],
[4,5,6],
[7,8,9] ]
for r in a.transposed() {print(r)}
// [1, 4, 7]
// [2, 5, 8]
// [3, 6, 9]
// note that the matrix cannot be sparse

Custom iterator to infinitely iterate collection in a loop mode

I am looking for iterator to infinitely iterate collection in a loop mode. So that when end index of collection is reached, then iterator should return element at start index.
The following solution seems working, but I hope it can be made in a better way.
public struct LoopIterator<T: Collection>: IteratorProtocol {
private let collection: T
private var startIndexOffset: T.IndexDistance
public init(collection: T) {
self.collection = collection
startIndexOffset = 0
}
public mutating func next() -> T.Iterator.Element? {
guard !collection.isEmpty else {
return nil
}
let index = collection.index(collection.startIndex, offsetBy: startIndexOffset)
startIndexOffset += T.IndexDistance(1)
if startIndexOffset >= collection.count {
startIndexOffset = 0
}
return collection[index]
}
}
extension Array {
func makeLoopIterator() -> LoopIterator<Array> {
return LoopIterator(collection: self)
}
}
// Testing...
// Will print: 1, 2, 3, 1, 2, 3
var it = [1, 2, 3].makeLoopIterator()
for _ in 0..<6 {
print(it.next())
}
Is it a right way to do custom iterator? What can be improved?
Thanks!
In Swift 3 (which you're using), indexes are intended to be advanced by the collection itself. With that, you can simplify this as follows:
public struct LoopIterator<Base: Collection>: IteratorProtocol {
private let collection: Base
private var index: Base.Index
public init(collection: Base) {
self.collection = collection
self.index = collection.startIndex
}
public mutating func next() -> Base.Iterator.Element? {
guard !collection.isEmpty else {
return nil
}
let result = collection[index]
collection.formIndex(after: &index) // (*) See discussion below
if index == collection.endIndex {
index = collection.startIndex
}
return result
}
}
Now we simply move the index forward, and if it now points to the end, reset it to the beginning. No need for count or IndexDistance.
Note that I've used formIndex here, which exists to improve performance in somewhat obscure cases (specifically around AnyIndex) since your Iterator works on any Collection (and therefore any Index). The simpler version would be index = collection.index(after: index), and that may be better in most cases.
For all the gory details on Swift 3 indices, see SE-0065.
With Swift 5, you can use one of the following examples in order to solve your problem.
#1. Using AnyIterator
As an alternative to creating a new type that conforms to IteratorProtocol, you can use AnyIterator. The following code, based on Rob Napier's answer, shows how to use it:
extension Array {
func makeInfiniteLoopIterator() -> AnyIterator<Element> {
var index = self.startIndex
return AnyIterator({
if self.isEmpty {
return nil
}
let result = self[index]
index = self.index(after: index)
if index == self.endIndex {
index = self.startIndex
}
return result
})
}
}
Usage:
let infiniteLoopIterator = [1, 2, 3].makeInfiniteLoopIterator()
for val in infiniteLoopIterator.prefix(5) {
print(val)
}
/*
prints:
1
2
3
1
2
*/
let infiniteLoopIterator = [1, 2, 3].makeInfiniteLoopIterator()
let array = Array(infiniteLoopIterator.prefix(7))
print(array) // prints: [1, 2, 3, 1, 2, 3, 1]
let infiniteLoopIterator = [1, 2, 3].makeInfiniteLoopIterator()
let val1 = infiniteLoopIterator.next()
let val2 = infiniteLoopIterator.next()
let val3 = infiniteLoopIterator.next()
let val4 = infiniteLoopIterator.next()
print(String(describing: val1)) // prints: Optional(1)
print(String(describing: val2)) // prints: Optional(2)
print(String(describing: val3)) // prints: Optional(3)
print(String(describing: val4)) // prints: Optional(1)
#2. Using AnySequence
A similar approach is to use AnySequence:
extension Array {
func makeInfiniteSequence() -> AnySequence<Element> {
return AnySequence({ () -> AnyIterator<Element> in
var index = self.startIndex
return AnyIterator({
if self.isEmpty {
return nil
}
let result = self[index]
self.formIndex(after: &index) // alternative to: index = self.index(after: index)
if index == self.endIndex {
index = self.startIndex
}
return result
})
})
}
}
Usage:
let infiniteSequence = [1, 2, 3].makeInfiniteSequence()
for val in infiniteSequence.prefix(5) {
print(val)
}
/*
prints:
1
2
3
1
2
*/
let infiniteSequence = [1, 2, 3].makeInfiniteSequence()
let array = Array(infiniteSequence.prefix(7))
print(array) // prints: [1, 2, 3, 1, 2, 3, 1]

Iterate over collection two at a time in Swift

Say I have an array [1, 2, 3, 4, 5]. How can I iterate two at a time?
Iteration 1: (1, 2)
Iteration 2: (3, 4)
Iteration 3: (5, nil)
You can use a progression loop called stride(to:, by:) to iterate over your elements every n elements:
let array = Array(1...5)
let pairs = stride(from: 0, to: array.endIndex, by: 2).map {
(array[$0], $0 < array.index(before: array.endIndex) ? array[$0.advanced(by: 1)] : nil)
} // [(.0 1, {some 2}), (.0 3, {some 4}), (.0 5, nil)]
print(pairs) // "[(1, Optional(2)), (3, Optional(4)), (5, nil)]\n"
To iterate your collection subsequences instead of tuples:
extension Collection {
func unfoldSubSequences(limitedTo maxLength: Int) -> UnfoldSequence<SubSequence,Index> {
sequence(state: startIndex) { start in
guard start < self.endIndex else { return nil }
let end = self.index(start, offsetBy: maxLength, limitedBy: self.endIndex) ?? self.endIndex
defer { start = end }
return self[start..<end]
}
}
}
let array = Array(1...5)
for subsequence in array.unfoldSubSequences(limitedTo: 2) {
print(subsequence) // [1, 2] [3, 4] [5]
}
This would work on any kind of collection:
let string = "12345"
for substring in string.unfoldSubSequences(limitedTo: 2) {
print(substring) // "12" "34" "5"
}
You can use sequence() and the iterator's next() method to iterate
over pairs of consecutive elements. This works for arbitrary sequences,
not only arrays:
let a = "ABCDE"
for pair in sequence(state: a.makeIterator(), next: { it in
it.next().map { ($0, it.next()) }
}) {
print(pair)
}
Output:
("A", Optional("B"))
("C", Optional("D"))
("E", nil)
The “outer” it.next() yields the elements at even positions, or nil
(in which case it.next().map { } evaluates to nil as well, and the
sequence terminates). The “inner” it.next() yields the elements
at odd positions or nil.
As an extension method for arbitrary sequences:
extension Sequence {
func pairs() -> AnyIterator<(Element, Element?)> {
return AnyIterator(sequence(state: makeIterator(), next: { it in
it.next().map { ($0, it.next()) }
}))
}
}
Example:
let seq = (1...).prefix(5)
for pair in seq.pairs() { print(pair) }
Note that the pairs are generated lazily, no intermediate array
is created. If you want an array with all pairs then
let pairs = Array([1, 2, 3, 4, 5].pairs())
print(pairs) // [(1, Optional(2)), (3, Optional(4)), (5, nil)]
does the job.
This is not identically what was asked, but I use an extension on Sequence that generates an array of arrays chunking the original sequence by any desired size:
extension Sequence {
func clump(by clumpsize:Int) -> [[Element]] {
let slices : [[Element]] = self.reduce(into:[]) {
memo, cur in
if memo.count == 0 {
return memo.append([cur])
}
if memo.last!.count < clumpsize {
memo.append(memo.removeLast() + [cur])
} else {
memo.append([cur])
}
}
return slices
}
}
So [1, 2, 3, 4, 5].clump(by:2) yields [[1, 2], [3, 4], [5]] and now you can iterate through that if you like.
Extension to split the array.
extension Array {
func chunked(into size: Int) -> [[Element]] {
return stride(from: 0, to: count, by: size).map {
Array(self[$0 ..< Swift.min($0 + size, count)]) }
}
}
let result = [1...10].chunked(into: 2)
I personally dislike looping through half the list (mainly because of dividing), so here is how I like to do it:
let array = [1,2,3,4,5];
var i = 0;
while i < array.count {
var a = array[i];
var b : Int? = nil;
if i + 1 < array.count {
b = array[i+1];
}
print("(\(a), \(b))");
i += 2;
}
You loop through the array by incrementing by 2.
If you want to have nil in the element, you need to use optionals.
If the array would have an even number of elements, you would be able to write something like this:
for i in 0..<arr.count/2 {
print(arr[2*i...2*i+1])
}
However that's not always the case. Moreover, nil is not always compatible with the type of elements in array, like the one in your example (nil is not compatible with Int, only with Int?).
Another solution would be to extend Array and add a pair() method, which returns a tuple (tuples can be heterogenous). You can use pair to walk within all pairs in the array, or, you can extend even more the Array struct and add pairs() that return an array of tuples. Note that since the second element in the tuple is an Optional you'll need to unwrap it before use.
extension Array {
func pair(at i: Index) -> (Element, Element?) {
return (self[i], i < self.count - 1 ? self[i+1] : nil)
}
func pairs() -> [(Element, Element?)] {
guard !isEmpty else { return [] }
var result = [(Element, Element?)]()
for i in 0...arr.count/2 {
result.append(self.pair(at: 2*i))
}
return result
}
}
let arr = [1, 2, 3, 4, 5]
for i in 0...arr.count/2 {
print(arr.pair(at: 2*i))
}
for pair in arr.pairs() {
print(pair)
}
Update Both above solutions can be simplified by using map instead of manually looping:
let pairs = (0..<arr.count/2).map { (arr[$0*2], arr[$0*2+1]) }
print(pairs) // prints [(1, 2), (3, 4)]
or, for the Array extension:
extension Array {
func pair(at i: Index) -> (Element, Element?) {
return (self[i], i < self.count - 1 ? self[i+1] : nil)
}
func pairs() -> [(Element, Element?)] {
guard !isEmpty else { return [] }
return (0..<(arr.count/2 + arr.count%2)).map { pair(at: $0*2) }
}
}
let arr = [1, 2, 3, 4, 5]
print(arr.pairs()) // [(1, Optional(2)), (3, Optional(4)), (5, nil)]
You can extend Collection instead, to have this pair functionality available for all collections:
extension Collection {
func pairs() -> [(Element, Element?)] {
guard !isEmpty else { return [] }
return (0..<count/2+count%2).map {
let i1 = index(startIndex, offsetBy: $0*2)
let i2 = index(after: i1)
return (self[i1], i2 < endIndex ? self[i2] : nil)
}
}
}
Here is my solution with one reduce and a few guards
extension Array {
var touplesOfTwo: [(Element,Element?)] {
self.reduce(into: [(Element,Element?)]()) {
guard let last = $0.last else { $0.append( ($1,nil) ); return }
let lastIndex = $0.count - 1
guard let _ = last.1 else { $0[lastIndex].1 = $1; return }
$0.append( ($1,nil) )
}
}
}
let list = [1,4,3,7,2,9,6,5]
let queues = list.map { $0 }
let touplesList = queues.touplesOfTwo
print("\(touplesList)")
// [(1, Optional(4)), (3, Optional(7)), (2, Optional(9)), (6, Optional(5))]
One approach would be to encapsulate the array in a class. The return values for getting pairs of items would be optionals to protect against out-of-range calls.
Example:
class Pairs {
let source = [1, 2, 3, 4, 5] // Or set with init()
var offset = 0
func nextpair() -> (Int?, Int?) {
var first: Int? = nil
var second: Int? = nil
if offset < source.count {
first = source[offset]
offset++
}
if offset < source.count {
second = source[offset]
offset++
}
return (first, second)
}
}

Xcode Swift: extension of array: "can't invoke.. with argument list .. " [duplicate]

I am trying to write a simple Array extension that provides a 'distinct' method. Here is what I have so far:
extension Array {
func distinct() -> T[] {
var rtn = T[]()
for x in self {
var containsItem = contains(rtn, x)
if !containsItem {
rtn.append(x)
}
}
return rtn
}
}
The problem is that the 'contains' statement fails as follows:
Could not find an overload for 'contains' that accepts the supplied arguments
I am pretty sure the type constraints are correct. Any ideas?
Swift 1.x
The elements in an array don't have to be Equatable, i.e. they don't have be comparable with ==.
That means you can't write that function for all possible Arrays. And Swift doesn't allow you to extend just a subset of Arrays.
That means you should write it as a separate function (and that's probably why contains isn't a method, either).
let array = ["a", "b", "c", "a"]
func distinct<T: Equatable>(array: [T]) -> [T] {
var rtn = [T]()
for x in array {
var containsItem = contains(rtn, x)
if !containsItem {
rtn.append(x)
}
}
return rtn
}
distinct(array) // ["a", "b", "c"]
Update for Swift 2/Xcode 7 (Beta)
Swift 2 supports restricting extensions to a subset of protocol implementations, so the following is now allowed:
let array = ["a", "b", "c", "a"]
extension SequenceType where Generator.Element: Comparable {
func distinct() -> [Generator.Element] {
var rtn: [Generator.Element] = []
for x in self {
if !rtn.contains(x) {
rtn.append(x)
}
}
return rtn
}
}
array.distinct() // ["a", "b", "c"]
Note how apple added SequenceType.contains using the same syntax.
Finally found out how to do it:
extension Array {
func contains<T : Equatable>(obj: T) -> Bool {
return self.filter({$0 as? T == obj}).count > 0
}
func distinct<T : Equatable>(_: T) -> T[] {
var rtn = T[]()
for x in self {
if !rtn.contains(x as T) {
rtn += x as T
}
}
return rtn
}
}
And usage/testing:
let a = [ 0, 1, 2, 3, 4, 5, 6, 1, 2, 3 ]
a.contains(0)
a.contains(99)
a.distinct(0)
Unfortunately, I can't figure out a way to do it without having to specify an argument which is subsequently ignored. The only reason it's there is to invoke the correct form of distinct. The major advantage of this approach for distinct seems to be that it's not dumping a common term like distinct into the global namespace. For the contains case it does seem more natural.
Another solution is to use the find(Array:[T], obj:T) function. It will return an optional Int, so what you could do is
if let foundResult = find(arr, obj) as Int
{
//obj is contained in arr
} else
{
//obj is not contained in arr.
}
As of Swift 2, this can be achieved with a protocol extension method,
e.g. on all types conforming to SequenceType where the sequence
elements conform to Equatable:
extension SequenceType where Generator.Element : Equatable {
func distinct() -> [Generator.Element] {
var rtn : [Generator.Element] = []
for elem in self {
if !rtn.contains(elem) {
rtn.append(elem)
}
}
return rtn
}
}
Example:
let items = [1, 2, 3, 2, 3, 4]
let unique = items.distinct()
print(unique) // [1, 2, 3, 4]
If the elements are further restricted to be Hashable then you
can take advantage of the Set type:
extension SequenceType where Generator.Element : Hashable {
func distinct() -> [Generator.Element] {
return Array(Set(self))
}
}