moveToBeginning() does move nothing but half of item .....WTF is this;

Community Beginner ,
Mar 29, 2021 Mar 29, 2021

Copy link to clipboard

Copied

hello 
 
im trying to move pathItems that each has a common appearence into the layer had made on time start beggning script 
 
im using moveToBeginning() 
but it moves item but nothing half of items 
i dont know why happen such a thing....
 
finally , just i want to do is moving all particlar pathitems to another layer
thank you for anything help
 

2021-03-30 151644.png
↑Script RESULT
 
↓Test SCRIPT
var parentLay = app.activeDocument.layers;
var Layer = app.activeDocument.layers.add();
 
 function DoSomeThing() {
            for (var j = 0j < parentLay[1].pageItems.lengthj++) {
                //↓moveToBeginning move nothing but half of pageitem ...why?
                parentLay[1].pageItems[j].moveToBeginning(Layer);
            }
 };
 DoSomeThing();



TOPICS
Bug, Scripting

Views

257

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

Enthusiast , Mar 29, 2021 Mar 29, 2021
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--.

Likes

Translate

Translate
Advocate , Mar 30, 2021 Mar 30, 2021
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();

Likes

Translate

Translate
Enthusiast ,
Mar 29, 2021 Mar 29, 2021

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 30, 2021 Mar 30, 2021

Copy link to clipboard

Copied

Thanks a lot!! (;_;)

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 30, 2021 Mar 30, 2021

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 30, 2021 Mar 30, 2021

Copy link to clipboard

Copied

Thank you for everything! (;c;)

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 30, 2021 Mar 30, 2021

Copy link to clipboard

Copied

thankyoueveryone.png
it had succeed , thank you very much every person......!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 30, 2021 Mar 30, 2021

Copy link to clipboard

Copied

Nice!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Mar 30, 2021 Mar 30, 2021

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. 

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 30, 2021 Mar 30, 2021

Copy link to clipboard

Copied

@DilliamWowling  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

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 30, 2021 Mar 30, 2021

Copy link to clipboard

Copied

i will trying read manytimes :c:, thank you for explain for essence of this isuue !

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Mar 31, 2021 Mar 31, 2021

Copy link to clipboard

Copied

LATEST

any time. if you have questions, please let me know and I can help explain whatever you need.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines