I have read Kotlin doc
<init>(size: Int, init: (Int) -> Boolean)
Creates a new array of the specified size, where each element is calculated by calling the specified init function.
The function init is called for each array element sequentially starting from the first one. It should return the value for an array element given its index.
Common
JVM
JS
Native
(size: Int)
Creates a new array of the specified size, with all elements initialized to false.
Constructor Creates a new array of the specified size, with all elements initialized to false.
<init>(size: Int)
Creates a new array of the specified size, with all elements initialized to false.
Constructor Creates a new array of the specified size, with all elements initialized to false.
also try simple code
var booleanArray = <init>(30)
it still not working. any help?
In the documentation, <init> refers to a constructor. You should replace it with the name of the class, which is how you call a constructor. In this case:
var booleanArray = BooleanArray(30)
var booleanArray = BooleanArray(candies.size)
This is how I init dynamic array
Tenfour04's answered your question about <init>, but just to be clear: wherever it talks about "the function init" it's talking about the init parameter in one of the constructors. This is a function which takes an Int (which will be an index in the array) and returns a Boolean value (which will be the value at that index in the array).
So you can make this extremely very useful array:
val oddNumbers = Boolean(100) { it % 2 == 1 }
which will pass in index 0, do 0 % 2 and get 0, which isn't equal to 1, so index 0 is set to false, then the same for index 1 which ends up true, and so on.
Or you can ignore the index and just set the same value for everything:
val allTrue = Boolean(100) { true }
All the array constructors work like this, so you can easily set a default value or fill each index with different values
Related
I'm using FloatArray:
private val values = FloatArray(5)
At some point, I need to reset each array value to zero. I tried doing it like this:
values.onEachIndexed { index, value -> value[index] = 0.0f }
But I am getting this error
No set method providing array access
At the same time, this code works (outside onEachIndexed) and I can set the value for the element:
values[1] = 4.0f
What am I doing wrong ? Please help me
Your attempt does not work because value there represents an element of the array, not the array itself, so you cannot use [] to set it. Reassigning it a new value will not work either, because value is a lambda parameter.
There is a builtin method for filling the entirety (or a portion) the array - fill
values.fill(0.0f)
I have an array and I first check if the array has the index of given number. I like to assign a value at that index if the array has not got any.
var newArray:Array = [0,1,2,3];//length is 4
if(newArray[5] == "")//true
{
newArray[5] = 5;
}
Adobe Help page says;
Inserting array elements
...
If the Array or Vector doesn’t already have an element at that index, the index is created and the value is stored there. If a value exists at that index, the new value replaces the existing one.
But I am not sure it is about null elements or undefined.
How can I assign a value to index that doesn't exist?
I can push till the given index but wondering is anything else possible.
array reference its elements as not typed so if an element does not exist it can be only undefined (default value for untyped) so in your case no need to check for null or "", you only need to check for undefined.
if(newArray[5] == undefined)
{
newArray[5] = 5;
}
EDIT:
undefined is a keyword in as3 that defines a default value for untyped objects. It is the value you use to check if an untyped object has no current value. (As opposed to a typed object that has null as default value with the exception of numbers).
Using "" as you suggest doesn't work since it is a valid String value and would only work to check if a String object is not null and has a length of 0. Equivalent of String.length == 0.
The assignment is correct, even though the index 4 does not exist at this point the Array Object does not complain and assign the value to index 5.
I'm new to scala/java and I have troubles getting the difference between those two.
By reading the scala doc I understood that ArrayBuffer are made to be interactive (append, insert, prepend, etc).
1) What are the fundamental implementation differences?
2) Is there performance variation between those two?
Both Array and ArrayBuffer are mutable, which means that you can modify elements at particular indexes: a(i) = e
ArrayBuffer is resizable, Array isn't. If you append an element to an ArrayBuffer, it gets larger. If you try to append an element to an Array, you get a new array. Therefore to use Arrays efficiently, you must know its size beforehand.
Arrays are implemented on JVM level and are the only non-erased generic type. This means that they are the most efficient way to store sequences of objects – no extra memory overhead, and some operations are implemented as single JVM opcodes.
ArrayBuffer is implemented by having an Array internally, and allocating a new one if needed. Appending is usually fast, unless it hits a limit and resizes the array – but it does it in such a way, that the overall effect is negligible, so don't worry. Prepending is implemented as moving all elements to the right and setting the new one as the 0th element and it's therefore slow. Appending n elements in a loop is efficient (O(n)), prepending them is not (O(n²)).
Arrays are specialized for built-in value types (except Unit), so Array[Int] is going to be much more optimal than ArrayBuffer[Int] – the values won't have to be boxed, therefore using less memory and less indirection. Note that the specialization, as always, works only if the type is monomorphic – Array[T] will be always boxed.
The one other difference is, Array's element created as on when its declared but Array Buffer's elements not created unless you assign values for the first time.
For example. You can write Array1(0)="Stackoverflow" but not ArrayBuffer1(0)="Stackoverflow" for the first time value assignments.
(Array1 = Array variable & ArrayBuffer1 = ArrayBuffer variable)
Because as we know, Array buffers are re-sizable, so elements created when you insert values at the first time and then you can modify/reassign them at the particular element.
Array:
Declaring and assigning values to Int Array.
val favNums= new Array[Int](20)
for(i<-0 to 19){
favNums(i)=i*2
}
favNums.foreach(println)
ArrayBuffer:
Declaring and assigning values to Int ArrayBuffer.
val favNumsArrayBuffer= new ArrayBuffer[Int]
for(j<-0 to 19){
favNumsArrayBuffer.insert(j, (j*2))
//favNumsArrayBuffer++=Array(j*3)
}
favNumsArrayBuffer.foreach(println)
If you include favNumsArrayBuffer(j)=j*2 at the first line in the for loop, It doesn't work. But it works fine if you declare it in 2nd or 3rd line of the loop. Because values assigned already at the first line now you can modify by element index.
This simple one-hour video tutorial explains a lot.
https://youtu.be/DzFt0YkZo8M?t=2005
Use an Array if the length of Array is fixed, and an ArrayBuffer if the length can vary.
Another difference is in term of reference and value equality
Array(1,2) == Array(1,2) // res0: Boolean = false
ArrayBuffer(1, 2) == ArrayBuffer(1,2) // res1: Boolean = true
The reason for the difference is == routes to .equals where Array.equals is implemented using Java's == which compares references
public boolean equals(Object obj) {
return (this == obj);
}
whilst ArrayBuffer.equals compares elements contained by ArrayBuffer using sameElements method
override def equals(o: scala.Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (
o match {
case it: Seq[A] => (it eq this) || (it canEqual this) && sameElements(it)
case _ => false
}
)
Similarly, contains behaves differently
Array(Array(1,2)).contains(Array(1,2)) // res0: Boolean = false
ArrayBuffer(ArrayBuffer(1,2)).contains(ArrayBuffer(1,2)) // res1: Boolean = true
This is NOT about min/max values!
I use Array with all kinds of indices like 0, 1, 2, 1000, -1, -100. Yes, negative indices (I like this feature and I'm thankful for it.). The problem is I need them to be negative otherwise I would have to move all items. Now I wonder how can I retrieve the min index like -100. Most elements between min and max index would be undefined.
var a: Array = new Array();
a[-100] = "hello";
a.forEach(...); // starts with 0
Is there a simple way to get min index ?
No, there is no simple way to get the minimum index of the negative keys. You would have to loop through all the keys, convert them to numbers, and get the lowest.
The reason for that is that you are using the array both as an array and as an object. The array only has items with positive indexes, when you assign anything to it using a negative index, it's instead added as a property to the array object, not as an item in the array.
The forEach method loops through the items in the array, so it will only access the positive indexes. The data that you added using negative indexes are not array items, they are properties of the array object. So, it's not a bug that the forEach method starts from index 0.
If you want to loop through everything that you stored in the array, you can loop through its properties, then you will get both the object properties and array items:
for (i in a) {
// Here i is the key, and a[i] is the value
}
It's true that you can have negative indices in AS3 Arrays. The problem (and it's quite a serious one) is that none of the Array methods recognise the negative indices - they only recognise whole numbers.
For example:
var my_array:Array = new Array();
var my_array[-100] = "hello";
trace(my_array[-100]) // hello
trace(my_array.length) // 0
trace(my_array) // [empty]
So standard iteration through the array can only be done with absolute references to the index. Or by treating the array as an Object when looping:
var lowest:int = -100000 /* some deep number */
for(var i in a){
if(int(i) < lowest){
lowest = int(i);
}
}
I have this foreach loop to check for collision and i want platform(movieclip) to be removed in case of collision. So far i've come up with this:
if (mcContent.mcPlayer.y + mcContent.mcPlayer.height > platformCloud.y)
{
mcContent.mcPlayer.y = platformCloud.y - mcContent.mcPlayer.height - 1;
jump();
mcContent.removeChild(platformCloud);
//platformsCloud.splice(platformCloud);
}
What this is doing is, removing the movieclip (ok so far so good) but without the splice, when the loop runs again through the array it is still there. So with the splice that is commented out there's 1 little problem, it removes all the movieclips from the array, apprently.
How can i splice only the current index that is being checked?
.splice() accepts a start index and an amount of items to remove, not the object you want to remove from the array.
Parameters
startIndex:int — An integer that specifies the index of the element in the array where the insertion or deletion begins. You can use a negative integer to specify a position relative to the end of the array (for example, -1 is the last element of the array).
deleteCount:uint — An integer that specifies the number of elements to be deleted. This number includes the element specified in the startIndex parameter. If you do not specify a value for the deleteCount parameter, the method deletes all of the values from the startIndex element to the last element in the array. If the value is 0, no elements are deleted.
You want to do this:
var index:int = platformsCloud.indexOf(platformCloud);
platformsCloud.splice(index, 1);
Why not just create a new array of the items to keep? Use Array.push to add new items. This may actually be more efficient than modifying the existing array. It also doesn't require keeping track of indices (which are required to use Array.splice).
Example code:
var keptPlatforms = [];
// do stuff
if (mcContent.mcPlayer.y + mcContent.mcPlayer.height > platformCloud.y)
{
mcContent.mcPlayer.y = platformCloud.y - mcContent.mcPlayer.height - 1;
jump();
mcContent.removeChild(platformCloud);
} else {
keptPlatforms.push(platformCloud);
}
// later, after this cycle, use the new Array
platformClouds = keptPlatforms;
Now, the reason platformsCloud.splice(platformCloud) removes all items is because the first argument is coerced to an integer so it is equivalent to platformsCloud.splice(0) which says "remove the 0th-indexed item to the end of the array". And, this does indeed clear the array.
To use Array.splice, you'd have to do something like:
// inside a loop this approach may lead to O(n^2) performance
var i = platformClouds.indexOf(platformCloud);
if (i >= 0) {
platformClouds.splice(i, 1); // remove 1 item at the i'th index
}