Copy link to clipboard
Copied
The problem is most likely due to the was the way pageItems object works. The references it stores will point to the wrong objects when you move them around the document. (I know! It's surprising!)
With your for loop, going backwards through the list usually works. Start from length -1 and go down to zero; j--.
var parentLay = app.activeDocument.layers;
var oldLayer = parentLay[0];
var Layer = app.activeDocument.layers.add();
function DoSomeThing() {
for (var j = oldLayer.pageItems.length - 1; j > -1; j--) {
oldLayer.pageItems[j].moveToBeginning(Layer);
}
};
DoSomeThing();
Copy link to clipboard
Copied
The problem is most likely due to the was the way pageItems object works. The references it stores will point to the wrong objects when you move them around the document. (I know! It's surprising!)
With your for loop, going backwards through the list usually works. Start from length -1 and go down to zero; j--.
Copy link to clipboard
Copied
Thanks a lot!! (;_;)
Copy link to clipboard
Copied
var parentLay = app.activeDocument.layers;
var oldLayer = parentLay[0];
var Layer = app.activeDocument.layers.add();
function DoSomeThing() {
for (var j = oldLayer.pageItems.length - 1; j > -1; j--) {
oldLayer.pageItems[j].moveToBeginning(Layer);
}
};
DoSomeThing();
Copy link to clipboard
Copied
Thank you for everything! (;c;)
Copy link to clipboard
Copied
it had succeed , thank you very much every person......!
Copy link to clipboard
Copied
Nice!
Copy link to clipboard
Copied
In case anyone is wondering why this happens, let's look at an example. OP's code used moveToBeginning(), which I'm going to replace with splice() since they both remove something from the array so the results are the same.
let's use the following array:
var fruits = ["apple", "banana","pear", "pineapple"];
Now let's say i want to remove each item of the array. A for loop is a great candidate for the job. Have a look at the following loop, and the outputs.
for(var i=0; i<fruits.length; i++)
{
$.writeln(fruits.join(", ");
//this removes 1 element from the array at index i
fruits.splice(i,1);
}
//results
//i = 0 : "apple, banana, pear, pineapple"
//i = 1 : "banana, pear, pineapple"
//i = 2 : loop condition false because after removing 2 items, fruits.length = 2, which is not less than the current value of i, even though we haven't processed all the elements. the current contents of fruits is: ["banana, pineapple"]. (i = 2) is not less than (fruits.length = 2)
//i = 3 : script never gets here even though there were 4 elements in the array at the beginning of the loop
So wait. What happened there? Why didn't banana get removed on the second iteration of the loop? And why did the loop exit before processing all of the elements?
On the first iteration of the loop,
var fruits = ["apple", "banana","pear", "pineapple"];
element index 0 is removed because i = 0;
On the second iteration of the loop,
var fruits = ["banana","pear", "pineapple"];
element index 1 is removed because i = 1; since "apple" was removed, "banana" got shifted to the left and is now at index[0], but because of the loop variable being incremented, you're not removing "banana" as expected, you're removing "pear".
on the third iteration of the loop,
var fruits = ["banana", "pineapple"];
fruits.length = 2, and i = 2. (i < fruits.length) = false. exit loop
Hey! that's half the array being left behind! Ok. Cool. So now we know why a forward for loop doesn't work. So what can we do about it? As @m1b pointed out, reversing the loop and traversing the array "backwards" eliminates the problems that we saw above. Since the elements will be removed from the end to the beginning, no elements get shifted and their indexes remain consistent and predictable. So let's look at the same example above, but with a backwards for loop:
for(var i = fruits.length - 1; i >=0; i--)
{
$.writeln(fruits.join(", ");
//this removes 1 element from the array at index i
fruits.splice(i,1);
}
$.writeln("fruits.length = " + fruits.length);
$.writeln("fruits.join(', ') = " + fruits.join(", ");
//results
//i = 3 : "apple, banana, pear, pineapple"
//i = 2 : "apple, banana, pear"
//i = 1 : "apple, banana"
//i = 0 : "apple"
//"fruits.length = 0"
//"fruits.join(', ') = ''"
This time you can see that each element gets taken from the end of the array, leaving the other elements undisturbed until it's their turn to be yanked out (or skipped over based on some condition).
The same principles apply even if you are only moving/removing some elements of an array. If you start at the front and remove something, you may skip over something that you're looking for. So, any time you're going to be adding or removing elements during a loop, you're usually better served going backwards.
Copy link to clipboard
Copied
@Disposition_Dev I tried to explain this before. I don't think I did a good a job as you.
https://community.adobe.com/t5/illustrator/objects-names-to-a-text-block/m-p/11726592#M258101
Copy link to clipboard
Copied
i will trying read manytimes :c:, thank you for explain for essence of this isuue !
Copy link to clipboard
Copied
any time. if you have questions, please let me know and I can help explain whatever you need.