First n elements of an array (which can be nil) - ios

I would like to retrieve the first n elements of an array which could be nil and could also have less than n elements. Is there a "swifty" way to do it?
This works:
n=2
array = [1,2,3,4,5]
array.prefix(upTo: 2) // [1,2]
But I also want it to work with
array = [1] //I want to get [1]
or
array = nil //I want nil as return
Thanks!

You can use Optional.map and Sequence.prefix:
let n = 2
let array: [Int]? = [1,2,3,4,5]
let firstN = array.map { Array($0.prefix(n)) }
The result firstN is an optional array. It is nil if array
is nil, and an array with at most n elements of the given array
otherwise.
If an ArraySlice
result is good enough for your purpose then it can be
simplified to
let firstN = array?.prefix(n)
as #Duncan suggested.

Related

Unable to compare array value in swift ios

I'm a fresher in iOS
I'm unable to compare in an if statement.
It looks like:
for i in 0.. <array.count
{
if(array[i] == array[i+1])
{
let removedVal = array.remove(i+1)
}
}
The error shows on the if condition:
Binary operator '==' cannot be applied to two 'Any' operands
I googled it, but I am unable to understand what should I do in my case.
=======================================================================
Atlast able to find a solution.
And it worked for me
if ( ((tempArrayForTeamName[i]) as AnyObject).isEqual(tempArrayForTeamName[i+1] as AnyObject) )
need to compare array index position as Any object
And use .isEqual replace of ==
You have to Filter your Array
var newarray = [Int]()
let dictionary = ["A":0,"B":1,"C":1,"D":1,"E":1,"F":1,"G":1,"H":1,"J":0]
let newDictionary = dictionary.reduce([:]) { result, element -> [String: Int] in
guard element.value != 1 else {
return result
}
var newResult = result
newResult[element.key] = element.value
newarray.append(newResult[element.key]!)
return newResult
}
In Swift : Array is a Generic Structure, NSMutableArray is an Objective-C class[will work in Swift].
A NSMutableArray created is of type Any; an array that can contain heterogenous object(could be String, Int or Bool).
An Array is arbitrarily specilized to contain Any (using as [Any])
eg:
var array:Array = ["ABC", 123, true] as [Any]
var nsMutableArray : NSMutableArray = ["ABC", 123, true]
Generic Parameterization:
Even if there is an option to give generic parameterization(Datatype) to your NSMutableArray in Objective C[remember NSMutableArray in an Objective C class],this generic parameterization in unfortunately ignored/not allowed in Swift.
How to specify the datatype:
In Swift one cannot specify the datatype of a NSMutableArray.It would give a compilation error: Cannot specialize non-generic type NSMutableArray.
But one can always specify the datatype of Array(Swift structure) as say: Array<String>.
eg: var array:Array<String> = ["Tom", "Jerry", "Spike"]
Your code has another problem, consider your array has 3 items then i=2, and you are trying to access index 3 (i+1). And program will crash.
Crash point (array[i] == array[i+1])
Please declare specific types array for example
let myArray:[String] = ["a", "b", "c", "d"]

How to filter array of array based on another subarray

I am trying to filter an array of array, based on another subarray. I am giving example below to make the requirement more clear. Please note that order of filterArray is important. I can iterate myArrayofArray using for loop, and then compare the element of each iterated element with filterArray. But I think Filter can be used in this case to get the resultArray. But a bit confused, how I'll implement it.
myArrayofArray = [[1,0,2], [1,2,0], [1,3,4], [1,2,1]]
filterArray = [1,0]
resultArray = [1,0,2]
The easiest way would be
let result = myArrayofArray.filter { $0.starts(with: filterArray) }
This will return a [[Int]] with zero or more matching arrays.

Swift 2d array minimum

I have an 2d array like this:
let array= [ [0,2], [4,5], [4,1], [0,4] ]
and I'd like to get ONE element thats 0. index is the smallest in the array.
Result should be this:
let result = [0,2] // not also [0,4] because just the first one
This is what I've tried so far but obviously this is not a working solution :p
let result = array.filter { $0[1].map { return $0.min() } }
Thanks in advance, jonas
You can simply use Array.min then compare the first element of the nested arrays. min will return the first element in the original array that fits the minimum function in the closure in case there were several minima.
let array = [ [0,2], [4,5], [4,1], [0,4] ]
let result = array.min(by: {$0.first! < $1.first!}) //[0,2]

How to find first non-zero element of an Array?

Is there a way to grab the first non-zero element from an array of numbers?
I have an Array with many zeros at the beginning and I need only the first item that is not a zero.
For example:
let array = [0,0,0,0,25,53,21,77]
based on the above, the result should be 25.
What is the good way to achieve it?
You could get it like this:
let array = [0,0,0,0,25,53,21,77]
let firstNonZero = array.first { element -> Bool in
return element != 0
}
Or as a shorter version:
let firstNonZero = array.first(where: { $0 != 0 })
Note that firstNonZero would be an optional Int, so in case of array contains only zeros, firstNonZero would be nil.
Aside bar note: If you were wondering why to use first(where:) instead of filter(_:).first, you could check this question:
What is the difference between filter(_:).first and first(where:)?

How to sort array based on another arrays position?

I have a tableView with its style being Right Detail. I therefore have 2 arrays, one is for the textLabels data, and the other is for detailTextLabel.
There will be 2 "sort by" options. One will be sort by the textLabels data, and the second will sort by the detailTextlabels data. So when I sort the first array (textLabels array), the second array (detailTextLables array) will also have to get sorted based on the firstarray`.
I know how to sort arrays, but how can I sort one array based on another?
Here's how I sorted the array: (it's an array of Dates.
firstArray.sort({ (a, b) -> Bool in
a.earlierDate(b) == a
})
First, why not have two arrays? Because you only have one array of UITableViewCells and you want to keep all the data associated with a particular table view cell together. And it makes the need to try to coordinate the sorting of multiple arrays (what you are asking to do) unnecessary.
But if you really want to do that:
var array1 = ["1", "3", "2"]
var array2 = ["One", "Three", "Two"]
let sortedFoo = zip(array1, array2).sort { $0.0 < $1.0 }
array1 = sortedFoo.map { $0.0 }
array2 = sortedFoo.map { $0.1 }
The idea with the above code is that it combines the two arrays into one array of tuples, and then sorts them based on the elements in the first array, then breaks that single array back out into two separate arrays.
In other words, since you have to combine the two arrays into one to do the sort anyway, you might as well make them in a single array in the first place. :-)
It's a bit messy, but you can use enumerate to work with indices and elements at the same time:
array1.enumerate().sort {
return $0.element < $1.element
}.map {$0.element}
array1.enumerate().sort {
return array2[$0.index] < array2[$1.index]
}.map {$0.element}
But it's really much simpler/easier with one array.
struct Item {
let prop1: Int
let prop2: String
}
var array = [
Item(prop1: 1, prop2: "c"),
Item(prop1: 2, prop2: "b"),
Item(prop1: 3, prop2: "a")
]
array.sort { $0.prop1 < $1.prop1 }
array.sort { $0.prop2 < $1.prop2 }
How about using using positionOf on the sorted array to find the corresponding index in the I sorted array?

Resources