I have collection of a models.
I need remove first n elements from the collection.
I know, how get first n elements (.first(n)), but I can't remove it.
You could use shift:
while (n-- > 0) {
collection.shift();
}
Cheers.
You can reset the collection to the models after index n:
collection.reset(collection.slice(n));
Related
I know you shouldn't, I kind of know why. But I mean I don't understand my own code once I am trying really to think what's going on.
So I have an array with bunch of objects. I am iterating over it and once I find an object with specific type, I remove it from the array, and add another object into the array. So something like this:
var arr = parent.allchildren() //getting all the children in array
for ele in arr{
if(ele==somethingHere){
parent.remove(ele)
parent.add(new ele) //add new child into child array
}
}
If I have an array of 1,2,3,4,5, and I remove 3 and add a 6 while iterating, the actual array would be 1,2,4,5,6 but the array I am iterating would still be 1,2,3,4,5.
Which I think it would be fine, because at the end I still get what I want, which removed the element and added the element I need. However modifying the list while iterating it is bad and you shouldn't do that, but for my case I think it does what I need. What could be the potential issue in my case that I can't see?
One thing you may want to think about doing is making all of the changes at the end of the iteration. Instead of making the changes one by one, record the changes you want to make while iterating, and then actually make those changes once your loop is finished.
For example, you could make an array of elements to remove, and an array of elements to add.
//Our array where we record what we want to add
var elementsToAdd = [Any]()
//Our array of what elements we want to remove. We record the index at
//which we want to remove the element from the array
var indexesToRemoveAt = [Int]()
//Getting all the children in array
var arr = parent.allchildren()
//Enumerating an array allows us to access the index at which that
//element occurs. For example, the first element's index would be 0,
//the second element's index would be 1, the third would be 2, and so
//on
for (index,ele) in arr.enumerated() {
if(ele == somethingHere) {
indexesToRemoveAt.append(index)
elementsToAdd.append(newEle)
}
}
//Now that we have recorded the changes we want to make, we could make
//all of the changes at once
arr.remove(at: indexesToRemoveAt)
arr.append(contentsOf: elementsToAdd)
Note that removing array elements at multiple indexes would require the following extension to Array. If you wanted to avoid creating this extension, you could always just loop through the array of indexes and tell the array to remove at each individual index. All this extension function is really doing is looping through the indexes, and removing the array element at said index.
Array extension to remove elements at multiple indexes:
extension Array {
//Allows us to remove at multiple indexes instead of just one
mutating func remove(at indexes: [Int]) {
for index in indexes.sorted(by: >) {
if index <= count-1 {
remove(at: index)
}
}
}
}
I just tested in a playground with the following code:
var arr = ["hi", "bye", "guy", "fry", "sky"]
for a in arr {
if arr.count >= 3 {
arr.remove(at: 2)
}
print(a)
}
print(arr)
This prints:
hi
bye
guy
fry
sky
["hi", "bye"]
So it looks like when you use a for-in loop in Swift, the array is copied and changes you make to it will not affect the array you are iterating over. To answer your question, as long as you understand that this is the behavior, there's nothing wrong with doing this.
I have an array of objects, some of which are movieclips and some instances of classes. I need to remove an item from the array but are struggling with how best to identify which array index to delete.
I am currently using this code, which does work
var i:int;
for (i = 0; i < list.length; i++) {
if (list[i].toString() == '[object myClass]') {
trace('found', i);
list.removeAt(i);
}
}
I am thinking a better way must exist to get the object name and without looping through the array.
I could use a little clarification on how you want to identify the object(s) that should be removed. If you are looking to simply remove any object that is an instance of the myClass class, I would recommend the is keyword.
Also, a warning, removing items from a list as you are iterating over it is just asking for trouble. If you remove object at index [0] then the object that used to be at index [1] is now index [0], but your for loop is going to increment i by one at the end of each iteration, so you will never check index [0] again. Thus you may skip one or more of the objects that you wanted to remove.
Instead try iterating over it backwards-- that should resolve that problem.
Here is what both of those recommendations together looks like:
for (var i:int = (list.length - 1); i >= 0; i--)
{
if (list[i] is myClass)
{
trace("found", i);
list.removeAt(i);
}
}
I'm looping through an array and splicing specific elements out, but my loop breaks after the first iteration because I'm skipping over an index when one is removed. I see here How to iterate over an array and remove elements in JavaScript that you can use an original loop and start from the top of the array and decrement i, but can I do this same thing using lodash?
Read about remove, filter and forEachRight methods. You should find the answer.
Instead of using a for-loop, you could just remove elements with lodash's filter or remove instead:
var array = [1, 10, 100, 1000];
function isLargerThan10(num) {
return num > 10;
}
// return the filtered array:
var filtered = _.filter(array, isLargerThan10);
console.log(filtered);
// modify the array:
_.remove(array, isLargerThan10);
console.log(array);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
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
}
How can add element to array in ActionScript3
If i have an array:
var myArray:Array;
How can add element to this array "myArray", something like this:
myArray[] = value;
My second question is: How can compare if variable value exist in array element value?
Something like in_array function in php
1. All of these are different ways of adding item to array.
someArray.push(someValue); : add last item
someArray.unshift(someValue); : add first item
someArray[index] = someValue; : set item somewhere
someArray.splice(index, 0, someValue); : insert item somewhere
2. Checking if a value is present in array.
if (someArray.indexOf(someValue) == -1) { /*value is not present*/ }
Refer to ActionScript language reference on Adobe livedocs.
To answer both your questions here, you can add to an array by direct access or by the push() method, like so:
myArray[7] = something;
or
myArray.push(something);
Also as Nox noted, you can use the splice method as well to add in elements. This method is used to delete N amount of elements at a specific index, but you can also simultaneously inject one or more elements at the same index.
For your second question about how to check values or compare them in an array, here is one method:
var i:int = 0;
for(i; i < myArray.length; ++i){
if(myArray[i] == 10){
trace('found');
}
}