Determine Size of Multidimensional Array in Swift - arrays

I am new to Swift and am struggling to work out how to determine the size of a multidimensional array.
I can use the count function for single arrays, however when i create a matrix/multidimensional array, the output for the count call just gives a single value.
var a = [[1,2,3],[3,4,5]]
var c: Int
c = a.count
print(c)
2
The above matrix 'a' clearly has 2 rows and 3 columns, is there any way to output this correct size.
In Matlab this is a simple task with the following line of code,
a = [1,2,3;3,4,5]
size(a)
ans =
2 3
Is there a simple equivalent in Swift
I have looked high and low for a solution and cant seem to find exactly what i am after.
Thanks
- HB

Because 2D arrays in swift can have subarrays with different lengths. There is no "matrix" type.
let arr = [
[1,2,3,4,5],
[1,2,3],
[2,3,4,5],
]
So the concept of "rows" and "columns" does not exist. There's only count.
If you want to count all the elements in the subarrays, (in the above case, 12), you can flat map it and then count:
arr.flatMap { $0 }.count
If you are sure that your array is a matrix, you can do this:
let rows = arr.count
let columns = arr[0].count // 0 is an arbitrary value

You must ask the size of a specific row of your array to get column sizes :
print("\(a.count) \(a[0].count)")

If you are trying to find the length of 2D array which in this case the number of rows (or # of subarrays Ex.[1,2,3]) you may use this trick: # of total elements that can be found using:
a.flatMap { $0 }.count //a is the array name
over # of elements in one row using:
a[0].count //so elemints has to be equal in each subarray
so your code to get the length of 2D array with equal number of element in each subarray and store it in constant arrayLength is:
let arrayLength = (((a.flatMap { $0 }.count ) / (a[0].count))) //a is the array name

Related

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.

Modifying a numpy array efficiently

I have a numpy array A of size 10 with values ranging from 0-4. I want to create a new 2-D array B from this with its ith column being a vector corresponding to the ith element of A.
For example, the value 1 as the first element of A would correspond to B having a column vector [0,1,0,0,0] as it's first column. A having 4 as its third element would correspond to B having it's 3rd column as [0,0,0,1,0]
I have the following code:
import numpy as np
A = np.random.randint(0,5,10)
B = np.ones((5,10))
iden = np.identity(5, dtype=np.float64)
for i in range(0,10):
a = A[i]
B[:,i:i+1] = iden[:,a:a+1]
print A
print B
The code is doing what it's supposed to be doing but I am sure there are more efficient ways of doing this. Can anyone please suggest some?
That could be solved by initializing an array of zeros and then integer-indexing into it with indices from A and assigning 1s, like so -
M,N = 5,10
A = np.random.randint(0,M,N)
B = np.zeros((M,N))
B[A,np.arange(len(A))] = 1

swift: difference between an 2d array and a dictionary

I kinda get confused between the two. I know a dictionary is initialized like:
var Dictionary=[Int:Int]
and is like [1:100,2:150] or [1:"cat",2:"dog"].
But I'm kinda of confused about 2d arrays. I think it is initialized like:
var Arr=[Int[Int]]()
and looks like [[1,4],[5,3]] and It should have an x and y coordinate.
I was wondering if the two are interchangeable and which would work best when making this grid? And if I wanted to store information at coordinate [2,1]=6 which should I use?
[0,1,0,0]
[0,1,1,0]
[1,0,0,1]
Don't get confused by the fact that both arrays and dictionaries use [ ] symbols for their literals. The two are completely different. a dictionary is used when you have a set of keys and each key has an associated value. A 2d array is essentially a matrix of values.
For your little matrix you want a 2d array. You can create and initialize a 2d array like this:
var matrix : [[Int]] = Array(repeating: Array(repeating: 0, count: 10), count: 10)
This would create a 10x10 matrix filled with zeros. To set a value you can do:
matrix[x][y] = 6
as long as x is 0 to rows - 1 and y is 0 to columns - 1.
Or read a value like:
let value = matrix[x][y]

Accessing n-dimensional array in R using a function of vector of indexes

my program in R creates an n-dimensional array.
PVALUES = array(0, dim=dimensions)
where dimensions = c(x,y,z, ... )
The dimensions will depend on a particular input. So, I want to create a general-purpose code that will:
Store a particular element in the array
Read a particular element from the array
From reading this site I learned how to do #2 - read an element from the array
ll=list(x,y,z, ...)
element_xyz = do.call(`[`, c(list(PVALUES), ll))
Please help me solving #1, that is storing an element to the n-dimensional array.
Let me rephrase my question
Suppose I have a 4-dimensional array. I can store a value and read a value from this array:
PVALUES[1,1,1,1] = 43 #set a value
data = PVALUES[1,1,1,1] #use a value
How can I perform the same operations using a function of a vector of indexes:
indexes = c(1,1,1,1)
set(PVALUES, indexes) = 43
data = get(PVALUES, indexes) ?
Thank you
Thanks for helpful response.
I will use the following solution:
PVALUES = array(0, dim=dimensions) #Create an n-dimensional array
dimensions = c(x,y,z,...,n)
Set a value to PVALUES[x,y,z,...,n]:
y=c(x,y,z,...,n)
PVALUES[t(y)]=26
Reading a value from PVALUES[x,y,z,...,n]:
y=c(x,y,z,...,n)
data=PVALUES[t(y)]
The indexing of arrays can be done with matrices having the same number of columns as there are dimensions:
# Assignment with "[<-"
newvals <- matrix( c( x,y,z,vals), ncol=4)
PVALUES[ newvals[ ,-4] ] <- vals
# Reading values with "["
PVALUES[ newvals[ ,-4] ]

How do concatenation and indexing differ for cells and arrays in MATLAB?

I am a little confused about the usage of cells and arrays in MATLAB and would like some clarification on a few points. Here are my observations:
An array can dynamically adjust its own memory to allow for a dynamic number of elements, while cells seem to not act in the same way:
a=[]; a=[a 1]; b={}; b={b 1};
Several elements can be retrieved from cells, but it doesn't seem like they can be from arrays:
a={'1' '2'}; figure; plot(...); hold on; plot(...); legend(a{1:2});
b=['1' '2']; figure; plot(...); hold on; plot(...); legend(b(1:2));
%# b(1:2) is an array, not its elements, so it is wrong with legend.
Are these correct? What are some other different usages between cells and array?
Cell arrays can be a little tricky since you can use the [], (), and {} syntaxes in various ways for creating, concatenating, and indexing them, although they each do different things. Addressing your two points:
To grow a cell array, you can use one of the following syntaxes:
b = [b {1}]; % Make a cell with 1 in it, and append it to the existing
% cell array b using []
b = {b{:} 1}; % Get the contents of the cell array as a comma-separated
% list, then regroup them into a cell array along with a
% new value 1
b{end+1} = 1; % Append a new cell to the end of b using {}
b(end+1) = {1}; % Append a new cell to the end of b using ()
When you index a cell array with (), it returns a subset of cells in a cell array. When you index a cell array with {}, it returns a comma-separated list of the cell contents. For example:
b = {1 2 3 4 5}; % A 1-by-5 cell array
c = b(2:4); % A 1-by-3 cell array, equivalent to {2 3 4}
d = [b{2:4}]; % A 1-by-3 numeric array, equivalent to [2 3 4]
For d, the {} syntax extracts the contents of cells 2, 3, and 4 as a comma-separated list, then uses [] to collect these values into a numeric array. Therefore, b{2:4} is equivalent to writing b{2}, b{3}, b{4}, or 2, 3, 4.
With respect to your call to legend, the syntax legend(a{1:2}) is equivalent to legend(a{1}, a{2}), or legend('1', '2'). Thus two arguments (two separate characters) are passed to legend. The syntax legend(b(1:2)) passes a single argument, which is a 1-by-2 string '12'.
Every cell array is an array! From this answer:
[] is an array-related operator. An array can be of any type - array of numbers, char array (string), struct array or cell array. All elements in an array must be of the same type!
Example: [1,2,3,4]
{} is a type. Imagine you want to put items of different type into an array - a number and a string. This is possible with a trick - first put each item into a container {} and then make an array with these containers - cell array.
Example: [{1},{'Hallo'}] with shorthand notation {1, 'Hallo'}

Resources