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.)
Related
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)))
I have an array of value pairs I want to modify. I need to add and remove values from this array as well, so I used a list. When I tried to use a list, I encountered an error.
Error CS1612 - Cannot modify the return value of 'List<(int, float)>.this[int]' because it is not a variable
So I decided I would investigate. I tried using an array instead, and it... worked fine? The following code only throws an error on arr1[0].Item1 += 1;.
static void Main()
{
List<(int, float)> arr1 = new List<(int, float)>() { (0, 0) };
(int, float)[] arr2 = new (int, float)[1];
arr1[0].Item1 += 1; // This line
arr2[0].Item1 += 1;
}
Why are tuple arrays mutable, but lists are not? Is this because arrays are simple blocks of data you can modify easily, but lists have a lot of backend behind them that complicates things? Is there a simple way to get around this, or am I going to have to make my own custom class?
Why are tuple arrays mutable, but lists are not?
The list itself is mutable, but not in the way you're doing it. Note that this isn't anything specific to tuples - it's just the case for any mutable struct.
The list indexer getter returns a value (i.e. a copy of the tuple in your case) - so modifying that value wouldn't modify the copy in the list. The compiler is trying to avoid you making a change to a value that's about to be thrown away. Array access doesn't do that - arr2[0] refers to the variable within the array. (An array is effectively a collection of variables.)
If you want to mutate the list, you can have to fetch the tuple, mutate it, then put it back:
var tuple = arr1[0];
tuple.Item1++;
arr1[0] = tuple;
Note that this also explains why you can't use list access expressions as arguments for ref parameters, but you can do the equivalent for arrays:
public void Method(ref int x) => x++;
public void CallMethod()
{
var list = new List<int> { 0 };
var array = new int[] { 0 };
Method(ref list[0]); // Error
Method(ref array[0]); // Valid
}
I'm coding in kotlin, and i have a problem with the Arrays
I would make a function that return an Array of Car (for example), but that array is build by data from file
Exemple :
fun buildAllCar(data:string) : Array<Car> {
val array = arrayOfNulls<Location>(5) //In the real code, the size is retrieved by an other item
for(i in array.indices){
array[i] = buildACarByData(data); //Just so you could see a sample usage
}
return array.requireNoNulls()
}
Without the requireNoNulls() , the type of object returned is Array of Car?
Use this method is the only way to get an Array of Car or there is a other way?
Thanks for your help
You can initialize an array in Kotlin using a mapper function like so
val array = Array(size, mapper function)
So to construct an Array of non-nullable Car
fun buildAllCar(data: String): Array<Car> = Array(5) { buildACarByData(data) }
Change the code and modify return type of Array because when you apply return type, Kotlin check the nullablity so "?" define with safe call and return list if if the array list objects are null.
fun buildAllCar(data:string) : Array<Car?> {
val array = arrayOfNulls<Location>(5) //In the real code, the size is retrieved by an other item
for(i in array.indices){
array[i] = buildACarByData(data); //Just so you could see a sample usage
}
return array
}
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()
I have an array of int and it requires to send an object in a function and multiply every element in that array with 10 and return a new array. As in kotlin where the function argument are val, so we cannot change the value of current array.
While function arguments are "val's" in Kotlin, meaning you can't modify what object they point to, the object (in your case, the array) can still be mutable.
If you want to mutate the array that's passed to your function, you can certainly do that, this will change the values in the array for everyone who has a reference to it:
fun multiplyByTenInPlace(array: IntArray) {
for (i in array.indices) {
array[i] = array[i] * 10
}
}
If you want to create a new array instead to return with the new values:
fun multiplyByTen(array: IntArray): IntArray {
return array.map { it * 10 }.toIntArray()
}
Or better yet, without creating a list in the middle:
fun multiplyByTen(array: IntArray): IntArray {
return IntArray(array.size) { i -> array[i] * 10 }
}
Use MutableList or simple use var instead.