How to check if Array contains ClosedRange? - arrays

In my application written in Swift 4.2 I have the following code:
let arrayOfIntegers = [2, 1, 9, 5, 4, 6, 8, 7]
let unknownLowerBound = 4
let unknownUpperBound = 20
let closedRange = ClosedRange<Int>(uncheckedBounds: (lower: unknownLowerBound,
upper: unknownUpperBound))
let subRange = arrayOfIntegers[closedRange]
subRange.forEach { print($0) }
As you can guess when I am running this code I receive the following error: Fatal error: Array index is out of range. I want to prevent it.

You can check if the range of valid array indices “clamped” to
the given closed range is equal to that range:
let array = [1, 2, 3, 4, 5, 6, 7, 8]
let closedRange = 4...20
if array.indices.clamped(to: Range(closedRange)) == Range(closedRange) {
let subArray = array[closedRange]
print(subArray)
} else {
print("closedRange contains invalid indices")
}
Or, equivalently:
if array.indices.contains(closedRange.lowerBound)
&& array.indices.contains(closedRange.upperBound) {
// ...
}

Related

how to multiply the array element in to the next element and output as an array in Swift

var numbers = [2, 4, 3, 7]
var computed = numbers
print(computed)
I want to multiply the first element to next, until the last will multiply to the first element
example:
2*4, 4*3, 3*7, 7*2
and the output will be [8, 12, 21, 14]
I don't know the Swift language but the algorithm is pretty simple and does not depend on any technology. Try with this one:
let numbers = [2, 4, 3, 7]
let indexAndNum = numbers.enumerated().map { (index, element) in
return element * numbers[(index + 1) % numbers.count]
}
print(indexAndNum)
Live demo here
var resultArray = [Int]()
for (index, number) in numbers.enumerated() {
if index < numbers.count - 1 {
resultArray.append(number * numbers[index + 1])
} else {
resultArray.append(number * numbers[0])
}
}
print(resultArray)
Succincter version of Sebastian Kaczmarek's answer:-
let numbers = [2, 4, 3, 7]
let computed = numbers.enumerated().map { $1 * numbers[($0 + 1) % numbers.count] }
print(computed)
Output:-
[8, 12, 21, 14]

Optimize Swift function to find a specific set of combinations of 3 digits within a larger integer array

I'm working on a function that will help me quickly find all the upper structure triads (3-note chord) that I can add to a 4-note 7th chord to create a larger compound chord, as well of the roots and names of each triad. The example I'm testing right now is a 13#11 chord, which has the following degrees in a 12-note octave (when the root is 0): [0, 2, 4, 6, 7, 9, 10]*
*side note: [0, 4, 6, 7, 9, 10] would also match as a 13#11.
The base 7th chord is a dominant 7th: [0, 4, 7, 9].I already know which triads complete the chord: a major triad on the 9th, [2, 6, 9], and a diminished triad on the #11, 0, 6, 9 (only the 6 (#11th) and 9 (13th) are actually necessary to build a 13#11 chord; the 2 (9th) is optional).
I actually already have a function that will give me these results, I'm just wondering if there's a faster/more efficient way to do it? It just feels a little bulky/clunky right now. Any help would be appreciated.
Thanks!
Jake
extension Int {
func degreeInOctave() -> Int {
switch self {
case 0...11:
return self
case 12...:
return self - 12
default:
return self + 12
}
}
}
var ust: [Int] = [0, 2, 4, 6, 7, 9, 10]
let maj = [0, 4, 7]
let min = [0, 3, 7]
let aug = [0, 4, 8]
let dim = [0, 3, 6]
let sus4 = [0, 5, 7]
let sus2 = [0, 2, 7]
let triadDegs = [maj, min, aug, dim, sus4, sus2]
var triadRoots: [Int] = []
var triadQualities: [String] = []
func findUpperStructureTriads(degs: [Int]) {
let degCount = degs.count
var firstIndex = 0
while firstIndex < (degCount - 2) {
var secondIndex = firstIndex + 1
while secondIndex < (degCount - 1) {
var thirdIndex = secondIndex + 1
while thirdIndex < (degCount) {
var threeNoteGroup = [degs[firstIndex], degs[secondIndex], degs[thirdIndex]]
func checkForTriad(triad: [Int]) -> Bool {
if triadDegs.contains(triad) {
switch triad {
case maj:
triadQualities.append("major")
case min:
triadQualities.append("minor")
case aug:
triadQualities.append("augmented")
case dim:
triadQualities.append("diminished")
case sus4:
triadQualities.append("sus4")
case sus2:
triadQualities.append("sus2")
default:
()
}
return true
} else {
return false
}
}
if threeNoteGroup.contains(6), threeNoteGroup.contains(9){
var inversionCount = 0
var newGroup = threeNoteGroup.map {$0 - threeNoteGroup[0]}
while inversionCount < 3 {
func invert() {
newGroup = newGroup.map {($0 - newGroup[1]).degreeInOctave()}
let newlast = newGroup.remove(at: 0)
newGroup.append(newlast)
}
if checkForTriad(triad: newGroup) {
print(threeNoteGroup, threeNoteGroup[inversionCount])
triadRoots.append(threeNoteGroup[inversionCount])
break
}
invert()
inversionCount += 1
}
}
thirdIndex += 1
}
secondIndex += 1
}
firstIndex += 1
}
for i in 0...(triadRoots.count - 1) {
print(triadRoots[i], triadQualities[i])
}
}
findUpperStructureTriads(degs: ust)
outputs:
[0, 6, 9] 6
[2, 6, 9] 2
6 diminished
2 major

Count of Items in an Array within an Array on Swift 3

Let's say that I have some code like this:
let arr = [[1, 2], [3, 4, 5], [6, 7, 8, 9, 10]]
How would I define a function that it takes in a number i such that it goes to the ith array in arr and it prints the number of elements?
For example, let's say the function is called arrcount. Then,
arrcount(1) = 2, arrcount(2) = 3, and arrcount(3) = 5.
You don't actually need a function to achieve this:
arr[2].count // will return 5
Something along these lines should work
func countNumberOfItems(at index: Int, from arr: [Array<Any>]) -> Int? {
if index < arr.count, let temp = arr[index] as? Array {
return temp.count
} else {
return nil
}
}

How can I get the largest value from an integer array in a dictionary of arrays

I am trying to get the largest value in a dictionary of arrays and I need also get the key of that array.
This is how I get the largest value:
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
I would use max method in your dictionary values and get the maximum value from the resulting tuple values:
if let result = interestingNumbers.max(by: {$0.value.max() ?? 0 < $1.value.max() ?? 0}),
let maxValue = result.value.max() {
print(result.key) // "Square\n"
print(result.value) // "[1, 4, 9, 16, 25]\n"
print(maxValue) // 25
}
Why don't you use a tuple to hold the largest value?
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest: (kind: String?, number: Int) = (nil, 0)
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest.number {
largest = (kind, number)
}
}
}
Which can be further simplified to:
var largest: (kind: String?, number: Int) = (nil, 0)
for (kind, numbers) in interestingNumbers {
let max = numbers.max() ?? 0
if max > largest.number {
largest = (kind, max)
}
}
Another method is to flatten the values first into a (kind, number) sequence:
let flattened = interestingNumbers
.map { (kind, numbers) in numbers.map { (kind, $0) } }
.joined()
let largest = flattened.max(by: { $0.1 < $1.1} )
print(largest)
or you can realize that only the maximum value in every array is the most important, therefore :
let largestPerKind = interestingNumbers
.map { (kind, numbers) in (kind, numbers.max() ?? 0) }
let largest = largestPerKind.max(by: { $0.1 < $1.1} )
print(largest)
You can use Swift function's for that.
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
if let value = interestingNumbers.map ({ ($0, $1.max() ?? 0) }).max(by: { $0.1 < $1.1 }) {
print(value.0, value.1) // Square 25
}
Let's go with step by step
First I have created array of tuple with type [(String, Int)], with first place it will store group and on second place it will store max value from its corresponding array.
let array = interestingNumbers.map ({ ($0, $1.max() ?? 0) })
//[("Fibonacci", 8), ("Square", 25), ("Prime", 13)]
Now find the max Int from the array of tuple.
if let value = array.max(by: { $0.1 < $1.1 }) {
print(value.0, value.1) //Will print group here it is "Square 25"
}
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var largest_kind : String? =nil
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
largest_kind = kind
}
}
}

How to remove elements from array that match elements in another array

How to remove elements from array that match elements in another array?
Assume we have an array and we loop through it and find out which elements to remove:
var sourceItems = [ ... ]
var removedItems = [SKShapeNode]()
for item : SKShapeNode in sourceItems {
if item.position.y > self.size.height {
removedItems.append(item)
item.removeFromParent()
}
}
sourceItems -= removedItems // well that won't work.
You can use the filter function.
let a = [1, 2, 3]
let b = [2, 3, 4]
let result = a.filter { element in
return !b.contains(element)
}
result will be [1]
Or more succinctly...
let result = a.filter { !b.contains($0) }
Check out the Swift Standard Library Reference
Or you can use the Set type.
let c = Set<Int>([1, 2, 3])
let d = Set<Int>([2, 3, 4])
c.subtract(d)
Be mindful if using the Set option, that your results only be unique values and will not maintain the initial ordering, if that matters to you, whereas the Array filter option will maintain the initial array's order, at least what elements remain.
Swift 3
let c = Set<Int>([65, 1, 2, 3, 1, 3, 4, 3, 2, 55, 43])
let d = Set<Int>([2, 3, 4])
c.subtracting(d)
c = {65, 2, 55, 4, 43, 3, 1}
d = {2, 3, 4}
result = {65, 55, 43, 1}

Resources