How can I put specific Coordinates in an array in Swift? - arrays

in Swift Playgrounds I have solved a level where I had to place 16 Blocks at specific coordinates.
for example:
let B1 = Block;
world.place(B1, atColumn: 1, row: 6)
If you have to do this 16 times, it is kind of lot to write down and doesn’t look really good. So my Question is if it is possible to create an array with coordinates (if yes, how can I do that) to just need to write something like that:
world.place(Block(), at: coordinate)
Thank you already for your time and your answers.

You can create an array of named tuples and then loop over that array placing a block at each one:
let coordinates: [(column: Int, row: Int)] = [(1, 2), (3, 4)]
for coordinate in coordinates {
let B1 = Block
world.place(B1, atColumn: coordinate.column, row: coordinate.row)
}
or you can unpack the column and row directly by using:
for (column, row) in coordinates {
let B1 = Block
world.place(B1, atColumn: column, row: row)
}

Related

The matrix created by two arrays does not have expected dimensions

Here is my first question and I am totally newby in Python so bear with me!
I am developing a code and at this step I am trying to create a matrix with 2 rows and certain amount of columns. The first row is an array and the second is another array (with the same length), UaP and UbP as can be seen in the code hopefully.
As it can be seen UaP and UbP both are (1, 400), but when I try to create an array by combining two, the resulted matrix dimension will be (2,1,400) instead of expected 2 x 400 dimension.
I have tried different things but I dont get what I expected. Maybe there is a simple trick to solve it? Thanks in advance.
```python
import numpy as np
#some codes here
UaP = 0.5*(Ua-Ub90)
UbP = 0.5*(Ub+Ua90)
UabP = np.array([(UaP),(UbP)])
# shapes of arrays
UbP.shape
(1, 400)
UaP.shape
(1, 400)
UabP = np.array([(UaP),(UbP)])
UabP.shape
(2, 1, 400)
Thats because your first array has shape (1,400) instead of (400,).
You could try this:
import numpy as np
UaP = np.random.rand(1,400)
UbP = np.random.rand(1,400)
# first solution
UabP = np.array([UaP[0],UbP[0]])
print(UabP.shape)
# second soluton
UabP = np.array([UaP,UbP])
UabP = UabP.reshape(1,2,400)
UabP = UabP[0]
print(UabP.shape)

How to construct an n-dimensional array from data

I want to create a function that takes in a one-dimensional array of numbers and a shape, and returns an array that contains those numbers that has the shape given. For instance if I give it the array [1, 2, 3, 4] and the shape [2, 2] I want it to give me the two dimensional array [[1, 2], [3, 4]].
I know this is pretty simple, but my problem is specifying a return type.
I would like to avoid just using the [Any] return type for the function. Like if the given shape is two-dimensional, the return type should be [[Int]], 3 dimensional [[[Int]]], etc. How would I specify an integer array with an arbitrary number of dimensions as the return type? Is this even possible?
I'm pretty new to swift so I don't fully understand the whole philosophy of it yet. Thanks!
What you're describing is a matrix. That's not the same thing as an array of arrays. For example, the following is a legal [[Int]], but is an illegal Matrix2:
[[1, 2], [1]]
Swift doesn't have a built-in matrix type. You have to build your own. There are a lot of small projects out there to look for inspiration. I don't know if any are really baked enough to consider full implementations, but they're good enough to get you on the right track. They often want to include Accelerate, which greatly increases the complexity if you don't need it.
https://github.com/hollance/Matrix
https://github.com/stsievert/swix
The heart of any Matrix type, if you want to build your own, is something like this:
struct Matrix {
private var storage: [Int]
let rows: Int
let columns: Int
init(rows: Int, columns: Int) {
precondition(rows > 0 && columns > 0)
self.rows = rows
self.columns = columns
self.storage = Array(repeating: 0, count: rows * columns)
}
subscript(row: Int, column: Int) -> Int {
get {
return storage[row * columns + column]
}
set {
storage[row * columns + column] = newValue
}
}
}
The key point is that storage is just a flat array of elements, and you subscript into it by row and column.
One nice thing about this design is that your question falls out almost trivially, since your input is exactly the storage.
extension Matrix {
enum Error: Swift.Error {
case invalidShape
}
init(rowMajorValues: [Int], rows: Int, columns: Int) throws {
self.init(rows: rows, columns: columns)
guard storage.count == rowMajorValues.count else {
throw Error.invalidShape
}
storage = rowMajorValues
}
}

How to convert two associated arrays so that elements are evenly distributed?

There are two arrays, an array of images and an array of the corresponding labels. (e.g pictures of figures and it's values)
The occurrences in the labels are unevenly distributed.
What I want is to cut both arrays in such a way, that the labels are evenly distributed. E.g. every label occurs 2 times.
To test I've just created two 1D arrays and it was working:
labels = np.array([1, 2, 3, 3, 1, 2, 1, 3, 1, 3, 1,])
images = np.array(['A','B','C','C','A','B','A','C','A','C','A',])
x, y = zip(*sorted(zip(images, labels)))
label = list(set(y))
new_images = []
new_labels = []
amount = 2
for i in label:
start = y.index(i)
stop = start + amount
new_images = np.append(new_images, x[start: stop])
new_labels = np.append(new_labels, y[start: stop])
What I get/want is this:
new_labels: [ 1. 1. 2. 2. 3. 3.]
new_images: ['A' 'A' 'B' 'B' 'C' 'C']
(It is not necessary, that the arrays are sorted)
But when I tried it with the right data (images.shape = (35000, 32, 32, 3), labels.shape = (35000)) I've got an error:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
This does not help me a lot:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
I think that my solution is quite dirty anyhow. Is there a way to do it right?
Thank you very much in advance!
When your labels are equal, the sort function tries to sort on the second value of the tuples it has as input, since this is an array in the case of your real data, (instead of the 1D data), it cannot compare them and raises this error.
Let me explain it a bit more detailed:
x, y = zip(*sorted(zip(images, labels)))
First, you zip your images and labels. What this means, is that you create tuples with the corresponding elements of images and lables. The first element from images by the first element of labels, etc.
In case of your real data, each label is paired with an array with shape (32, 32, 3).
Second you sort all those tuples. This function tries first to sort on the first element of the tuple. However, when they are equal, it will try to sort on the second element of the tuples. Since they are arrays it cannot compare them en throws an error.
You can solve this by explicitly telling the sorted function to only sort on the first tuple element.
x, y = zip(*sorted(zip(images, labels), key=lambda x: x[0]))
If performance is required, using itemgetter will be faster.
from operator import itemgetter
x, y = zip(*sorted(zip(images, labels), key=itemgetter(0)))

Sorting a cell array of matrices based on numerical value in each matrix?

I am working on a coding project and ran into a roadblock. I have a cell array of 1x3 matrices. (1,1) encodes the value to sort by, (1,2) and (1,3) encode coordinates that i need for reference later. Is there any way to sort the cell array by the (1,1) values in each matrix within the larger cell array?
CombList = {[1,1,1], [5,1,2];
[4,1,3], [3,1,2];
[2,1,4], [2,1,3]};
I would like to sort by the first values in each matrix within the cell array. Ideally, it would return:
CombList = [1,1,1], [2,1,3];
[2,1,4], [3,1,2];
[4,1,3], [5,1,2]};
...once sorted:)
Thank you!
I believe the following should work. The result will be a numeric array, hope that will work for you.
CombList = {[1,1,1], [5,1,2];
[4,1,3], [3,1,2];
[2,1,4], [2,1,3]}
CombMat = cell2mat(CombList);
CombMat(:, 1:3) = sortrows(CombMat(:, 1:3));
CombMat(:, 4:6) = sortrows(CombMat(:, 4:6));
You can use mat2cell to get convert it back to a cell array, like this:
CombCell = mat2cell(CombMat, [1 1 1], [3 3])
Zany one-liner based on sortrows:
CombList = reshape(mat2cell(sortrows(cell2mat(reshape(CombList,[],1))),ones(numel(CombList),1),numel(CombList{1})),2,[]).';

How do I algorithmically instantiate and manipulate a multidimensional array in Scala

I am trying to wrote a program to manage a Database through a Scala Gui, and have been running into alot of trouble formatting my data in such a way as to input it into a Table and have the Column Headers populate. To do this, I have been told I would need to use an Array[Array[Any]] instead of an ArrayBuffer[ArrayBuffer[String]] as I have been using.
My problem is that the way I am trying to fill these arrays is modular: I am trying to use the same function to draw from different tables in a MySQL database, each of which has a different number of columns and entries.
I have been able to (I think) define a 2-D array with
val Data = new Array[Array[String]](numColumns)(numRows)
but I haven't found any ways of editing individual cells in this new array.
Data(i)(j)=Value //or
Data(i,j)=Value
do not work, and give me errors about "Update" functionality
I am sure this can't possibly be as complicated as I have been making it, so what is the easy way of managing these things in this language?
You don't need to read your data into an Array of Arrays - you just need to convert it to that format when you feed it to the Table constuctor - which is easy, as demonstrated my answer to your other question: How do I configure the Column names in a Scala Table?
If you're creating a 2D array, the idiom you want is
val data = Array.ofDim[String](numColumms, numRows)
(There is also new Array[String](numColumns, numRows), but that's deprecated.)
You access element (i, j) of an Array data with data(i)(j) (remember they start from 0).
But in general you should avoid mutable collections (like Array, ArrayBuffer) unless there's a good reason. Try Vector instead.
Without knowing the format in which you're retrieving data from the database it's not possible to say how to put it into a collection.
Update:
You can alternatively put the type information on the left hand side, so the following are equivalent (decide for yourself which you prefer):
val a: Array[Array[String]] = Array.ofDim(2,2)
val a = Array.ofDim[String](2,2)
To explain the syntax for accessing / updating elements: as in Java, a multi-dimensional array is just an array of arrays. So here, a(i) is element i of a, which an Array[String], and so a(i)(j) is element j of that array, which is a String.
Luigi's answer is great, but I'd like to shed some light on why your code isn't working.
val Data = new Array[Array[String]](numColumns)(numRows)
does not do what you expect it to do. The new Array[Array[String]](numColumns) part does create an array of array of strings with numColumns entries, with all entries (arrys of strings) being null, and returns it. The following (numRows) then just calls the apply function on that returned object, which returns the numRowsth entry in that list, which is null.
You can try that out in the scala REPL: When you input
new Array[Array[String]](10)(9)
you get this as output:
res0: Array[String] = null
Luigi's solution, instead
Array.ofDim[String](2,2)
does the right thing:
res1: Array[Array[String]] = Array(Array(null, null), Array(null, null))
It's rather ugly, but you can update a multidimensional array with update
> val data = Array.ofDim[String](2,2)
data: Array[Array[String]] = Array(Array(null, null), Array(null, null))
> data(0).update(0, "foo")
> data
data: Array[Array[String]] = Array(Array(foo, null), Array(null, null))
Not sure about the efficiency of this technique.
Luigi's answer is great, but I just wanted to point out another way of initialising an Array that is more idiomatic/functional – using tabulate. This takes a function that takes the array cell coordinates as input and produces the cell value:
scala> Array.tabulate[String](4, 4) _
res0: (Int, Int) => String => Array[Array[String]] = <function1>
scala> val data = Array.tabulate(4, 4) {case (x, y) => x * y }
data: Array[Array[Int]] = Array(Array(0, 0, 0, 0), Array(0, 1, 2, 3), Array(0, 2, 4, 6), Array(0, 3, 6, 9))

Resources