How to populate array of custom objects - arrays

class abc{
var name = String()
init(name:String){
self.name = name
}
}
var obj = [abc]()
obj[0] = abc(name:"sun")
obj[1] = abc(name:"sharma")

The issue is that you are trying to access elements of the array by subscript that don't exist by the time you're trying to access them.
var obj = [abc]() just initializes an empty array, so you cannot access its elements by subscript, since it doesn't have any elements yet.
You should use Array.append to add new elements to the end of your array.
var obj = [Abc]()
obj.append(Abc(name:"sun"))
obj.append(Abc(name:"sharma"))
You can also create the array straight away with the elements you want to store in it:
var obj = [Abc(name:"sun"),Abc(name:"sharma")]
After you have populate the array, you can access its elements in several ways. If you want to iterate through the array, you'll usually want to use the for...in.. loop:
for object in obj {
print(object.name)
}
If you want to access a single element, you can do that using array subscripts, but make sure the index doesn't exceed the array's size before using indexing.
let index = 1
if index < array.count { //safe to use index as subscript
print(obj[index])
}
You should also conform to the Swift naming convention, which is upperCamelCase for types (Abc instead of abc).

I think you are asking about creating an array of objects..
It is really easy
Consider you have two classes, Class A and Class B
Class A{
var name:String
init(localName: String){
self.name = localName
}
}
Class B{
//here you can create an array of objects of class A
//this will create an empty array of objects of class A
var objList = [A]()
//to add data into this array u can use append
func addData(objA: A){
self.objList.append(objA)
}
func displayData(list : [A]){
for entry in list{
print(entry.name)
}
}
}

Related

Array of array double won't adding a new element in kotlin

I have array of array double but it won't add element after using .plusElementor .plus. code below inside from view model that returns it.data which is a list of object
Code
var ageEntry : Int
val dataObject : Array<Array<Double>> = arrayOf()
for (dataWeight in it.data!!){
ageEntry = dataWeight.date.toLocalDate().getAgeInMonth().toString().toInt()
dataObject.plusElement(arrayOf(ageEntry.toDouble(), dataWeight.weight.toDouble()))
Log.d("DATA_SERIES_BARU", "setupViewInstance: ${dataObject.contentToString()}")
}
Log
The OP's proposed answer is subpar to say the least. If you need a mutable data structure, use a list not an array. I suggest something like this:
it.data?.fold(ArrayList<Array<Double>>()) { list, dataWeight ->
val ageEntry = dataWeight.date.toLocalDate().getAgeInMonth().toString().toInt()
list.add(arrayOf(ageEntry.toDouble(), dataWeight.weight.toDouble()))
list
}
If you absolutely need an array at the end, you can easily convert it using toTypedArray().
Im adding this function to add array Element
fun <T> appendArray(arr: Array<T>, element: T): Array<T?> {
val array = arr.copyOf(arr.size + 1)
array[arr.size] = element
return array
}
then you can call it
appendArray(copyDataObject, arrayOf(ageEntry,arrayOf(arrayOf(2.0, 3.0)))

Multidimensional array of Objects in Kotlin

I'm new in Kotlin, and I want to create a multi dimensional array of a custom class, with null permitted. Something like that
private var array_map = arrayOf<Array<Obstacle?>>()
...
array_map[1][2] = Obstacle()
How can I do it? Thank you!
In case you need the index of each element in the constructor of the elements of the array:
Declaration:
var matrix: Array<Array<Obstacle?>>
Instantiation and initialization:
matrix = Array(numRows) { row ->
Array(numCols) { col ->
Obstacle(row, col)
}
}
You can use private var arrayMap: Array<Array<Obstacle?>> = arrayOf(). Just wrap with as much Array<> as you need.
Not sure if this is what you want, but imagine that Obstacle is a custom class with a field num as below
data class Obstacle(var num: Int){}
A 2D array of the Obstacle object would be as below:
val array: Array<Obstacle?> = arrayOf(Obstacle(123), Obstacle(234))
val arrayOfArray: Array<Array<Obstacle?>> = arrayOf(array)
println(arrayOfArray[0][0]) // would print Obstacle(num=123)
println(arrayOfArray[0][1]) // would print Obstacle(num=234)
So you should be declaring your 2D array as below
val arrayOfArray: Array<Array<Obstacle?>> = arrayOf()
Your code will compile as is. The problem is just that array size can't be changed and arrayOf<Array<Obstacle?>>() creates an empty array, so array_map[1][2] = Obstacle() fails at runtime. (Unless you do array_map = ... somewhere between them. Note that you should prefer val arrayMap, which can't be reassigned, unless you have a specific reason to use var.)
If you want your array to start with nulls, there is arrayOfNulls in the standard library, but it only creates a single-dimensional array, and what you really need is an array of arrays of nulls. You can write a helper function:
inline fun <reified T> matrixOfNulls(n: Int, m: Int) = Array(n) { arrayOfNulls<T>(m) }
private val arrayMap = matrixOfNulls<Obstacle>(5, 5) // example arguments
The approach I always use for this case is:
arr2D = Array(sizeA) { Array(sizeB) { content } }
Note I replaced the sizes by fields names to illustrate that each number/field represents the width and height length of each dimension of the 2D array.
Also, content should be replaced by the main content you want to fill in each coordinate, in your case seems you aims to setup with Obstacle() instances. If you want fill this content in other moment put null or a quick Any() reference.
In this last case, after creating that you can simply perform to set the itens:
arr2D[1][2] = Obstacle()

How to assign an array of int and strings into one string variable in swift?

I have an array that takes in 2 types, a String and an Int the code looks like so
var totalDoubleSet1Array = [(Dante,10), (Cassius, 9), (Rio, 5)]
let sortedArray = totalDoubleSet1Array.sort { $0.1 > $1.1 }
I then use the sort function to arrange in order the highest score(Int) to the lowest with the name next to it. (So I can assign this to a string and display in an AlertAction)
I have seen it somewhere on here that yes I can print an Array of a single type of String or Int etc to the console but how can I Assign this array of 2 types (Stings and Ints) to a new Variable of String so I can assign it to a AlertAction message in swift please? Or even better how can I grab the individual element of each entry so I can assign it to a Var String? Hopefully this makes sense.. Thanks
This is not an "array of two types", it's an array of tuples. You can grab an item from the array and take its individual parts like this:
let (name, score) = totalDoubleSet1Array[i]
After this assignment you would get two variables - name of type String that has the value of i-th element's name, and score of type Int that has the value of i-th element's score.
If all you need is the name, you have two options:
You could use let (name, _) = totalDoubleSet1Array[i] syntax, or
You could use let name = totalDoubleSet1Array[i].1 instead.
Note that you are using the second syntax already in the comparison expression of your sorting function:
sort { $0.1 > $1.1 }
According Apple tuples are not the best choice for data structures...
Why not just using a custom struct
struct Player {
var name : String
var score : Int
}
let totalDoubleSet1Array = [Player(name:"Dante", score:10), Player(name:"Cassius", score:9), Player(name:"Rio", score:5)]
let sortedArray = totalDoubleSet1Array.sort { $0.score > $1.score }
Then you can easily access the name for example in a table view
let player = sortedArray[indexPath.row]
nameLabel.text = player.name

Xtend: Add element to array in for-loop

I am trying to do the simplest operation in Xtend, but don't know how. I want to add an double value to an double[] array inside a for-loop.
For example:
def do(EList<MyObject> list) {
var double[] array = newDoubleArrayOfSize(list.size);
for (i : 0 ..< list.size) {
array[i] = list.get(i).myValue;
}
return array;
}
The forth line shows an error, because I can't use array[i] = ....
How do I implement that in Xtend? Haven't found anything in the user guide.
Xtend has a different ("list-like") syntax for accessing array elements, see the related documentation for details:
Retrieving and setting values of arrays is done through the extension
methods get(int) and set(int, T) which are specifically overloaded for
arrays and are translated directly to the equivalent native Java code
myArray[int].
So your code should be:
def method(EList<MyObject> list) {
var double[] array = newDoubleArrayOfSize(list.size);
for (i : 0 ..< list.size) {
array.set(i, list.get(i).myValue);
}
return array;
}
You can further simplify your method by omitting semicolons and the type declaration of the array variable:
def method(EList<MyObject> list) {
val array = newDoubleArrayOfSize(list.size)
for (i : 0 ..< list.size) {
array.set(i, list.get(i).myValue)
}
return array
}
Another alternative is to write your method in a more functional style. If you can replace EList with List (or EList extends/implements List) then you could simply write:
def double[] method(List<MyObject> list) {
list.map[myValue]
}
In this case you must explicitly declare the return type as double[] because otherwise it would be inferred as List<Double>.
(Just one more thing: usually collections are preferred over arrays because they are more flexible and have more rich APIs, and Xtend has some additional goodies as well like collection literals.)

How do I make a exact duplicate copy of an array?

How would I make an exact duplicate of an array?
I am having hard time finding information about duplicating an array in Swift.
I tried using .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Arrays have full value semantics in Swift, so there's no need for anything fancy.
var duplicateArray = originalArray is all you need.
If the contents of your array are a reference type, then yes, this will only copy the pointers to your objects. To perform a deep copy of the contents, you would instead use map and perform a copy of each instance. For Foundation classes that conform to the NSCopying protocol, you can use the copy() method:
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
Note that there are pitfalls here that Swift's value semantics are working to protect you from—for example, since NSArray represents an immutable array, its copy method just returns a reference to itself, so the test above would yield unexpected results.
There is a third option to Nate's answer:
let z = x.map { $0 } // different array with same objects
* EDITED * edit starts here
Above is essentially the same as below and actually using the equality operator below will perform better since the array won't be copied unless it is changed (this is by design).
let z = x
Read more here: https://developer.apple.com/swift/blog/?id=10
* EDITED * edit ends here
adding or removing to this array won't affect the original array. However, changing any of the objects' any properties that the array holds would be seen in the original array. Because the objects in the array are not copies (assuming the array hold objects, not primitive numbers).
Nate is correct. If you are working with primitive arrays all you need to do is assign duplicateArray to the originalArray.
For the sake of completeness, if you were working an NSArray object, you would do the following to do a full copy of an NSArray:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
For normal objects what can be done is to implement a protocol that supports copying, and make the object class implements this protocol like this:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
And then the Array extension for cloning:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
and that is pretty much it, to view code and a sample check this gist
If you want to copy the items of an array of some class object.
Then you can follow the below code without using NSCopying protocol but you need to have an init method which should take all the parameters that are required for your object.
Here is the code for an example to test on playground.
class ABC {
var a = 0
func myCopy() -> ABC {
return ABC(value: self.a)
}
init(value: Int) {
self.a = value
}
}
var arrayA: [ABC] = [ABC(value: 1)]
var arrayB: [ABC] = arrayA.map { $0.myCopy() }
arrayB.first?.a = 2
print(arrayA.first?.a)//Prints 1
print(arrayB.first?.a)//Prints 2

Resources