AS3 am i using array.slice() currently? - arrays

I want to remove a value from a array, at a set index.
this is the while loop i have
while (i < objects.length)
{
var index:int = get_index(objects[i]);
if (index != -1)
{
Quadtree_list[index].insert(objects[i]);
objects.slice(i, 1);
} else {
i++;
}
}
sooner or later i cannot get out the loop, so it crashes
but if i replace objects.slice with object.pop, it works (but its not removing the right index)
quick note objects.slice(i, 1) is not reducing the length of the array but objects.pop() is, how do i make .slice() reduce the size of the array?.

Array.slice(x,y) returns an Array containing the elements from index x to index y.
I believe what you're after is Array.splice(startIndex, deleteCount), this is a multi-purpose function. In your code objects.splice(i, 1);
Starting from index (startIndex)
Remove elements up to deleteCount (1)
return an Array containing removed elements

Related

Recursively iterate over an array without changing its size

I am currently trying to solve this problem in Java, but I do not want to set myself onto a specific language since I think of this as a "general" problem.
The conditions for the function I am looking for are:
the only values that can be modified are the values inside the array to be iterated over. Thus, for example, you can not use other variables that store any kind of information, such as indices (which by the way also eliminates the possibility of looping through the array). This also applies to function parameters. The only argument that is passed to the function is the array itself.
additionally to the previous point: memory space must be consistent. Therefore, you cannot copy the current array onto a bigger/smaller array.
However:
the array is an integer array
the function might return an integer value
the elements inside the array might be changed, but only after they are iterated over
the array does not have to be iterated in any kind of order, but every element has to be "reached" exactly once.
there exists a function that returns the length of the array
the signature might look like this (again, no specific language, but since I am currently working in Java, the signature is in Java syntax):
int iterate(int[] integerArray)
Is it possible to write such a function?
One attempt of mine was to traverse the array from index 0 to length(array) - 1, storing the current index at array[0], and exit if array[0] (or array[prev]) is length(array) - 1. So, in order to get the next array element, I would do something like array[array[0]] and increment the counter in array[0]. The major problem with this is that I have to somehow catch the first function call to iterate() in order to initialize array[0] with 0.
This is not a variable but a parameter (the only thing we can work with, otherwise I don't see how it could work), here an example to find max:
function findMax(arr, index = 0, max = Number.MIN_VALUE) {
if (index < arr.length)
return findMax(arr, index + 1, arr[index] > max ? arr[index] : max)
return max
}
console.log(findMax([7,9,2,8,6]))
Or another example with modification, reverse array (without variable for the swap, alternatively you could just write a helper function to do the swapping):
function reverseArray(arr, index = 0, value = arr[0]) {
if (index < arr.length) {
reverseArray(arr, index + 1, arr[index + 1]) // iterate over the whole array
// any modification here will happen after the whole array was iterated
if (index < arr.length / 2) {
arr[index] = arr[arr.length - index - 1]
arr[arr.length - index - 1] = value
}
}
return arr
}
console.log(reverseArray([7,9,2,8,6]))
If you are using a language where you cannot specify predefined values, then you can just overload the method or create a helper, e.g. java:
public int findMax(int[] arr) {
findMax(arr, 0, arr[0]);
}
private int findMax(int[] arr, int i, int max) {
if (i < arr.length)
return findMax(arr, i + 1, arr[i] > max ? arr[i] : max);
return max;
}

Efficient way to filter an array based on element index

I have an array of arrays. So each element of my first array contains a comma separated list of values. If I use the split function, I can get an array from this comma separated list. What I need to do is filter out this second array based on element position. For example only keep columns one, three, five and nine.
One way to do this is loop thru my first array, for each element do a split on the element to get my second array. Then loop thru this second array, increment a counter to track the current element index. If the counter is equal to one of the columns I want to keep, then concat the element to a string variable.
This is very inefficient and takes forever to run on large arrays. Does anyone have any ideas on a better way to do this? I hope I explained this clearly.
There are some built in array actions like “Filter” and “Join” as you mention, but for something this specific I imagine you’ll need to call some code (e.g. azure function) to quickly do manipulation and return result
For the first loop I don't know of any alternate but for second loop, Instead of looping through the second array,you can simply access the elements with index that you require.
Assuming the size is not an issue.
string[] Arr1 = new string[] { "0_zero,0_One,0_Two,0_Three,0_Four,0_Five,0_six,0_seven,0_eight,0_nine",
"1_zero,1_One,1_Two,1_Three,1_Four,1_Five,1_six,1_seven,1_eight,1_nine" };
string myString = string.Empty;
foreach(var a in Arr1)
{
var sp = a.Split(',');
myString= string.Concat(myString, sp[0], sp[3], sp[5], sp[9]);
}
Console.WriteLine(myString); //gives "0_One0_Three0_Five0_nine1_One1_Three1_Five1_nine"
In case we're not sure of length of each string, we can use if else ladder with decreasing order from maximum index that we want to use like so
foreach(var a in Arr1)
{
var sp = a.Split(',');
int len = sp.Length;
if (len >= 10) myString= string.Concat(myString, sp[1], sp[3], sp[5], sp[9]);
else if (len >= 6) myString = string.Concat(myString, sp[1], sp[3], sp[5]);
else if (len >= 4) myString = string.Concat(myString, sp[1], sp[3]);
else if (len >= 2) myString = string.Concat(myString, sp[1]);
}
So that we don't face IndexOutofBoundsException

How can i set all items of an array to 0 in GameMaker studio?

Simple. I Need Help Setting All The Values Of An array to 0 in GameMaker: Studio.
This is because i need to test if i have not modified the array by using
if array[id] != 0 {
//Enter code
}
Of course, there are several ways, choose the best depending on the circumstances.
If you haven't filled anything in the array yet, adding a new item to a certain index initializes all previous values with "0":
var array;
array[length-1] = 0; //everything upto length-1 is filled
If you did already create the array and wish to reset it you should loop over it:
for (var i = array_get_length_1d(array) - 1; i >= 0; --i) {
array[i] = 0;
}
If you do not care about the original memory locations, and you can create a complete new array, creating a new one in place of the old one can be slightly faster:
array = 0; //destroys the old array
array[length - 1] = 0; //recreates like in the first option

How can i splice current index in a foreach?

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
}

actionscript subtract specific items from array

how do I remove specific items from my array that is hundreds of items long?
-eg:
var myArray:Array = ["dog", "cat", "bear", "duck", "frog", etc..., etc...];
What do I do when I want to remove "duck" from this array? Please keep in mind, that the array is very long and we do not know WHERE the "duck" is, so we don't know it's index in the array.
I need to get that item somehow by it's name and remove it from the array.
myArray.splice(myArray.indexOf("duck"), 1);
This is a straight-forward way of doing it:
Non-stable version (does less copying).
for (var i:int, j:int = array.length - 1, temp:Object; i <= j;) {
temp = array[i];
if (temp == "duck") {
array[i] = array[j];
array[j] = temp;
j--;
} else {
i++;
}
}
array.length = i;
And the stable version (more copying, but the order of the original array is unchanged):
for (var i:int, j:int, temp:Object; i < array.length; i++) {
temp = array[i];
if (temp != "duck") {
array[j] = temp;
j++;
}
}
array.length = j;
However, if you could assure that values are unique, the algorithm would be different, since you wouldn't have to verify items after the one you've found.
The algorithm would be significantly different, if the array was sorted because you could use binary search to find the element to remove. In some very peculiar situations, like, for example, if you have a well-founded set (which is your array), the deletion would be even simpler, because the position of the item you are searching for could be determined in constant time. The later can be mitigated through the use of indices (put simple, you could have a hash-table that uses elements of the array as its keys and their offsets into array as values).
Again, you need to consider all those cases and what is practical with regard to your program.
As I've mentioned above, there may be benefits if you use a different data structure, or if you sort on insert, or if you index on insert.
Lastly, producing a copy with undesired items removed is different from destructively removing items from the same array.
If your array is very long, it is well worth optimizing it somehow.
some options:
1) use a dictionary; the string can be the key. This has the added benefit of not re-indexing your list when you add/remove elements.
//specify weak keys when you create the dictionary
var myDictionary:Dictionary = new Dictionary(true);
//when you want to delete an item:
myDictionary["duck"] = null;
2) sort your array and use a binary search. There's lots of info about binary search online. Here's one SO question on the topic.
One way is to just use a while loop in combination with the indexOf method of an Array as such :
var index:int;
while ((index = myArray.indexOf("duck")) >= 0)
{
myArray.splice(index,1);
}
You could wrap that in a function and accept Array and String parameters, and return the resulting array like this :
function removeSearchString(sourceArray:Array, searchString:String):Array
{
var index:int;
while ((index = sourceArray.indexOf(search)) >= 0)
{
sourceArray.splice(index,1);
}
return sourceArray;
}
then you'd use the function like this :
myArray = removeSearchString(myArray, "duck");

Resources