Array in Swift Xcode - arrays

I have an algorithm that intersects some array with Bool and give me back some other array. Now the problem is that the arrays I get has this form:
[[[[123.0,334.45]]],[[[342.35,2434.34]]],[[[...,...]]],....]
Now how you can see there are too Square brackets, is there any way to remove the parentheses too ?
thanking you.

Whew, now that's nesting!
I counted the brackets, and used the appropriate number of joined() methods to flatten the array:
let array = [[[[123.0,334.45]]],[[[342.35,2434.34]]]]
let flatArray = Array(array.joined().joined().joined())
...gives:
[123, 334.45, 342.35, 2434.34]

Related

Get the index of the last occurrence of each string in an array

I have an array that is storing a large number of various names in string format. There can be duplicates.
let myArray = ["Jim","Tristan","Robert","Lexi","Michael","Robert","Jim"]
In this case I do NOT know what values will be in the array after grabbing the data from a parse server. So the data imported will be different every time. Just a list of random names.
Assuming I don't know all the strings in the array I need to find the index of the last occurrence of each string in the array.
Example:
If this is my array....
let myArray = ["john","john","blake","robert","john","blake"]
I want the last index of each occurrence so...
blake = 5
john = 4
robert = 3
What is the best way to do this in Swift?
Normally I would just make a variable for each item possibility in the array and then increment through the array and count the items but in this case there are thousands of items in the array and they are of unknown values.
Create an array with elements and their indices:
zip(myArray, myArray.indices)
then reduce into a dictionary where keys are array elements and values are indices:
let result = zip(myArray, myArray.indices).reduce(into: [:]) { dict, tuple in
dict[tuple.0] = tuple.1
}
(myArray.enumerated() returns offsets, not indices, but it would have worked here too instead of zip since Array has an Int zero-based indices)
EDIT: Dictionary(_:uniquingKeysWith:) approach (#Jessy's answer) is a cleaner way to do it
New Dev's answer is the way to go. Except, the standard library already has a solution that does that, so use that instead.
Dictionary(
["john", "john", "blake", "robert", "john", "blake"]
.enumerated()
.map { ($0.element, $0.offset) }
) { $1 }
Or if you've already got a collection elsewhere…
Dictionary(zip(collection, collection.indices)) { $1 }
Just for fun, the one-liner, and likely the shortest, solution (brevity over clarity, or was it the other way around? :P)
myArray.enumerated().reduce(into: [:]) { $0[$1.0] = $1.1 }

How to check if two identical array exist in a single two-dimensional array? [Swift]

if I have a two-dimensional array like this: [[1,2,3], [3,2,1], [4,9,3]], I want to be able to find out that there are two identical arrays inside this array, which are [1,2,3] and [3,2,1]. How can I achieve this?
Thank you for all your answers, I was focusing on the leetCode threeSum problem so I didn't leave any comment. But since I am a programming noobie, my answer exceeded the time limit.. so I actually wanted to find the duplicated arrays and remove all the duplicates and leave only one unique array in the multi-dimensional array. I have added some extra code based on #Oleg's answer, and thought I would put my function here :
func removeDuplicates(_ nums: inout [[Int]] ) -> [[Int]]{
let sorted = nums.map{$0.sorted()}
var indexs = [Int]()
for (pos,item) in sorted.enumerated() {
for i in pos+1..<sorted.count {
if item == sorted[i] {
if nums.indices.contains(i){
indexs.append(i)
}
}
}
}
indexs = Array(Set<Int>(indexs))
indexs = indexs.sorted(by: {$0 > $1})
for index in indexs{
nums.remove(at: index)
}
return nums
}
My solution is quite simple and easy to understand.
let input = [[1,2,3], [3,2,1], [4,9,3]]
First let sort all elements of the nested arrays. (It gives us a bit more efficiency.)
let sorted = input.map{$0.sorted()}
Than we should compare each elements.
for (pos,item) in sorted.enumerated() {
for i in pos+1..<sorted.count {
if item == sorted[i] {
print(input[pos])
print(input[i])
}
}
}
Output:
[1, 2, 3]
[3, 2, 1]
One simple and easy brute force approach that comes to my mind is:
Iterate over each row and sort its values. So 1,2,3 will become 123 and 3,2,1 will also become 1,2,3.
Now store it in a key value pair i.e maps. So your key will be 123 and it will map to array 1,2,3 or 3,2,1.
Note:- Your key is all the sorted elements combined together as string without commas.
This way you will know that how may pairs of arrays are there inside a 2d array are identical.
There is a very efficient algorithm using permutation hashing method.
1) preprocess the 2-dim array so that all elements are non-negative. (by subtracting the smallest element from all elements)
2) with each sub-array A:
compute hash[A] = sum(base^A[i] | with all indexes i of sub-array A). Choose base to be a very large prime (1e9+7 for example). You can just ignore the integer-overflow problem when computing, because we use only additions and multiplications here.
3) now you have array "hash" of each sub-array. If the array has 2 identical sub-arrays, then they must have the same hash codes. Find all pairs of sub-arrays having equal hash codes(using hash again, or sorting, ... whatever).
4) For each pair, check again if these sub-arrays actually match (sort and compare, ... whatever). Return true if you can find 2 sub-arrays that actually match, false otherwise.
Practically, this method runs extremely fast even though it is very slow theoretically. This is because of the hashing step will prune most of search space, and this hash function is super strong. I am sure 99.99% that if exist, the pair of corresponding sub-arrays having the same hash codes will actually match.

Ruby - elegantly flatten an array but don't ignore empty sub-arrays

Using .flatten is a handy little trick to take an array of sub-arrays and turn it into a single array.
For example: [[1,3],2,[5,8]].flatten => [1,3,2,5,8]
You can even include nil [1,[2,nil],3].flatten will result in [1,2,nil,3].
This kind of method is very useful when nesting a .map method, but how would you account for an empty sub-array? For example: [1,[2,3],[],4].flatten would return [1,2,3,4]... but what if I need to keep track of the empty sub array maybe turn the result into [1,2,3,0,4] or [1,2,3,nil,4]
Is there any elegant way to do this? Or would I need to write some method to iterate through each individual sub-array and check it one by one?
If you don't need to recursively check nested sub-arrays:
[1,[2,3],[],4].map { |a| a == [] ? nil : a }.flatten
First map the empty arrays into nils, then flatten
[1,2,[1,2,3],[]].map{|x| if x.is_a? Array and x.empty? then nil else x end}.flatten

Summing an Array of Tuples

I have an an array of tuples defined like this:
var stringsWithLengthsArray:[(someString: String, someStringLength: Int)] = []
I've appended a number of tuples to this array. I would like to sum the someStringLength elements of each tuple in the array and think the best way to do this is to use the stringsWithLengthsArray.reduce method, but I can't figure out the syntax. What's the best way to sum the someStringLength elements?
I like this way best:
let total = stringsWithLengthsArray.reduce(0){$0 + $1.someStringLength}
This is another solution. Use reduce without map and access your tuple fields with the .0 / .1 accessors directly.
let total = stringsWithLengthsArray.reduce(0){$0 + $1.1}
You can use map to get only the someStringLength property value and use reduce to sum all the elements as follow:
let stringsWithLengthsArray:[(someString: String, someStringLength: Int)] = [("strA",2),("strB",3)]
let someStringLenghtTotal = stringsWithLengthsArray.map{$0.someStringLength}.reduce(0){$0+$1}
someStringLenghtTotal // 5

Taking a column or row of a 2D Array in F#

How can I get hold of a column or row of a 2D Array in F# (ideally as a 1D array, but a Seq would be nice as well). Obviously I could write it myself, but you would think it must be already provided...
E.g. I am after built-in equivalent for:
let row i array = seq { for j in 0 .. (Array2D.length2 array)-1 do yield array.[i,j]}
I don't think there is a built-in function for this.
You could slice the array and flatten the slice using Seq.cast:
let row i (arr: 'T[,]) = arr.[i..i, *] |> Seq.cast<'T>

Resources