Пересортировка коллекции в процессе перебора.

  • Автор темы Автор темы dhead
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

dhead

Участник
Топикстартер
Сообщения
48
Реакции
0
Имеется коллекция линков. Необходимо обновлять или не обновлять каждый из них, в зависимости от дополнительных условий. Проблема в том, что после обновления элемента коллекции происходит ее пересортировка, что делает невозможным перебирать ее в цикле или с помощью for .. in. Как с этим бороться ?
 
Ответ: Пересортировка коллекции в процессе перебора.

Перебирать надо for in только в обратную сторону.
 
Ответ: Пересортировка коллекции в процессе перебора.

Перебирать надо for in только в обратную сторону.
Не пойдет - вы ж не уверены, что добавление именно в конец идет? Вообще, данных мало, нужно конкретизировать задачу.
 
Ответ: Пересортировка коллекции в процессе перебора.

Конкретизировать как раз не хотелось, поскольку такая проблема периодически возникает с разными коллекциями. Кажется вспомнил, как раньше обходил ее. Можно сделать так:1. отобрать в цикле нужные элементы коллекции, сохраняя в отдельном массиве их имена или ID. 2. в цикле перебрать все элементы массива, внося необходимые изменения в элементы коллекции, обращаясь к ним через itemByName или itemByID. Пересортировка тут не помешает.
 
Ответ: Пересортировка коллекции в процессе перебора.

Конкретизировать как раз не хотелось
Тем не менее придется. Ибо все зависит именно от того как вы модифицируете элементы коллекций? При правильном подходе такого просто не должно быть!
 
Ответ: Пересортировка коллекции в процессе перебора.

Тем не менее придется. Ибо все зависит именно от того как вы модифицируете элементы коллекций? При правильном подходе такого просто не должно быть!
К примеру, такой кусок:
Код:
  var llist="";
  var lname;
  var nOk=0;
  var nErr=0;            
  var aDoc=app.activeDocument;
  for (n=0;n<aDoc.links.length;n++){
     lname=aDoc.links.item(n).name;
     if (lname.indexOf("ng_0")==0){
        nOk++
        try{
           aDoc.links.item(n).update();
           llist=llist + lname + " - OK\n"
        }
        catch(myError){
            nErr++;
            llist=llist + lname +" - Ошибка!\n"
        }
     }
  }
После этого alert(llist," Обновленных линков: " + (nOk-nErr).toString() +" из " +nOk.toString()) выдает такое:

Буфер обмена01.png

Если убрать строку с апдейтом, то все выглядит так, как ожидалось: перебраны все нужные линки.

Буфер обмена02.png

Очевидно, в первом случае после апдейта происходит пересортировка коллекции. То есть либо глюк\особенность, либо неправильный подход, либо такого не должно быть :)
 
Ответ: Пересортировка коллекции в процессе перебора.

С тремя линкованными текстами повторить проблему не удалось: вне зависимости от того, все тексты изменены и требуют апдейта или не все, их индексация, а значит и порядок обработки не меняются. А Ваши скрины только добавили вопросов.
Один из них: куда в первом алерте подевались файлы 007, 003, 051, 008? Из второго алерта следует, что 007 - это линк с нулевым индексом, а значит должен быть обработан и записан в отчет в любом случае.
В общем, мне лично ничего не понятно. Попробуйте что-нибудь определить, записав в алерт индексы и ID каждого линка до и после апдейта.
 
Ответ: Пересортировка коллекции в процессе перебора.

куда в первом алерте подевались файлы 007, 003, 051, 008? Из второго алерта следует, что 007 - это линк с нулевым индексом, а значит должен быть обработан и записан в отчет в любом случае.

Файлы пропадают (а другие попадают в список по несколько раз подряд) именно потому, что коллекция после каждого апдейта пересортируется, а цикл перебирает по "прежнему" порядку. Вот еще скрин с ID: ID1 - до апдейта и ID2 - сразу после него.

Буфер обмена03.png

Самое забавное - две последние строчки. Мало того, что у линка на файл 007 ID меняется после апдейта, он еще раз успевает измениться до того, как к нему подходит очередь в новой (пересортированной) коллекции, несмотря на то, что за это время ни одного апдейта не происходит, поскольку в новой коллекции он идет сразу за самим собой:)
Код:
for (n=0;n<aDoc.links.length;n++){   lname=aDoc.links.item(n).name;
   if (lname.indexOf("ng_0")==0){
      nOk++
      try{
         llist=llist + lname + " ID1=" + aDoc.links.item(n).id.toString();
         aDoc.links.item(n).update();
         llist=llist + " ID2=" + aDoc.links.item(n).id.toString()+ " - OK\n";
       }
       catch(myError){
         nErr++;
         llist=llist + lname +" - Ошибка!\n"
       }
    }
}

P.S.
Все это наблюдаю на английском CS3.

Кстати, предложенный мной выше вариант решения надо скорректировать: список из id элементов составлять бесполезно. Только из имен и дальше перебирать их с помощью itemByName. Тогда все работает правильно.
Еще раз хочу сказать, что такие же глюки наблюдал раньше и с другими коллекциями, правда подробностей уже не помню.
 
Ответ: Пересортировка коллекции в процессе перебора.

Все это наблюдаю на английском CS3.
Хм...
Не знаю как откомментировать... Скрипт один и тот же, порядок вставки текстов один, всё идентично, но:

CS3:
updateTextLinkCS3.jpg

CS5:
updateTextLinkCS5.jpg
 
Ответ: Пересортировка коллекции в процессе перебора.

Хм...
Не знаю как откомментировать...
Вот и я не знаю.
Но очевидно, что баг или особенность(весьма неприятная) у CS3 зафиксирован.
Работающее решение есть - перебор через itemByName по предварительно составленному списку имен(при условии, что линков с одинаковыми именами нет). Если других предложений не будет, то наверное тему можно закрывать.
Правда есть вопрос-предложение: не нашел тему багов и способов их обходов в разделе скриптинга. Думаю, она была бы весьма познавательной и в отдельных случаях помогала бы экономить массу времени.
 
Ответ: Пересортировка коллекции в процессе перебора.


Не по теме:
По ходу в этом разделе каждый топик и так содержит в себе описание очередного бага в адобовском скриптинге ;)
 
Ответ: Пересортировка коллекции в процессе перебора.


Не по теме:
По ходу в этом разделе каждый топик и так содержит в себе описание очередного бага в адобовском скриптинге ;)

Не по теме:
Несколько преувеличиваете, по-моему:) Мне кажется, смысл в отдельной теме все-таки есть. Что скажет модератор?
 
Ответ: Пересортировка коллекции в процессе перебора.


Не по теме:
Что скажет модератор?
1. Что касается этой темы — если это и баг, то получается, что он исправлен в следующих версиях программы, а значит по логике не может считаться актуальным.
2. Множество вопросов по скриптам, поначалу кажущихся багами, удаётся в итоге объяснить логически. Часто ответы не находятся потому, что просто не остаётся желания их найти (желание исчезает, когда появляется альтернативное решение, после чего и время на поиск ответа тратить неохота, работа важнее))).
3. С другой стороны, раз возникло предложение, значит Вы видели достаточно большое количество тем, описывающих баги. Если Вы мне их покажете, и их наберётся действительно внушительное количество, я придумаю, как их собрать до кучи.

Эту тему во избежание дальнейшего оффтопа прикрою, дальнейшее обсуждение мне в ЛС.

 
Статус
Закрыто для дальнейших ответов.