Kotlin Array manipulation - arrays

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.

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)))

C# - Tuple arrays are mutable, but tuple lists are not. How do I get around this?

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
}

Kotlin - Array of object (no null)

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
}

Extend swift Array -- mutability issue

I would like to create a Swift 4 extension on a Swift Array. The function should sort the array in-place.
The compiler complains seems to assume that arrays are immutable, as it complains on the function I created. I'd like to solve this, but do not know how. Please do note that the requirement is to sort the array in-place (with sort) and not creating a new array (like one would do with sorted).
struct MyStruct {
var field: String
}
typealias MyStructList = [MyStruct]
// requirement: extend MyStructList with custom sort
extension Array where Element == MyStruct {
func customSort() -> [MyStruct] {
return sort { $0.field < $1.field }
}
}
Compiler complains: Cannot use mutating member on immutable value: 'self' is immutable
You want to be calling sorted(by:), which returns a new, sorted Array instance rather than sort(by:), which does sorting in place and hence mutates the Array.
extension Array where Element == MyStruct {
func customSort() -> [MyStruct] {
return sorted(by: {$0.field < $1.field})
}
}
If you actually want to sort the Array in place, you have to mark your customSort function as mutating and change the function signature to return Void, since there's no new Array created.
extension Array where Element == MyStruct {
mutating func customSort() {
sort(by: {$0.field < $1.field})
}
}
Two issues:
You have to mark the function as mutating
If you want to sort in place there is no return value
extension Array where Element == MyStruct {
mutating func customSort() {
sort { $0.field < $1.field }
}
}
And please name methods / functions camelCased.
sort is a mutable function that sorts an Array in-place. sorted(by:) is the function you are looking for. Rename sort to sorted.
If you are looking to sort the Array in-place, then rewrite your function declaration to include the mutating qualifier.
So the following:
func custom_sort()
becomes:
mutating func custom_sort()
The mutating function sort(by:) does not return anything, therefore your return is erroneous. Remove -> [MyStruct] as well.

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.)

Resources