Удаление элементов из массива данных - PullRequest
0 голосов
/ 26 марта 2009

Как удалить элементы из массива данных? Мой код следует.

for(var i = 0; i < listBox.selectedIndices.length; i++) {
  var toRemove = listFiles.selectedIndices[i];
  dataArray.splice(toRemove, 1);
}

Заранее спасибо!

Редактировать Вот мой swf. Добавить фотографии работает, кроме случаев, когда вы удаляете элементы. http://www.3rdshooter.com/Content/Flash/PhotoUploader.html

  1. Добавить 3 фото разных.
  2. Удалить 2-е фото.
  3. Добавить другое фото.
  4. SWF добавляет второе фото в конец.

Любые идеи о том, почему это будет делать?

Редактировать 2 Вот мой код

private function OnSelectFileRefList(e:Event):void
{
    Alert.show('addstart:' + arrayQueue.length);
    for each (var f:FileReference in fileRefList.fileList)
    {
         var lid:ListItemData = new ListItemData();
         lid.fileRef = f;
         arrayQueue[arrayQueue.length]=lid;
    }
    Alert.show('addcomplete:' + arrayQueue.length);
    listFiles.executeBindings();
    Alert.show(ListItemData(arrayQueue[arrayQueue.length-1]).fileRef.name);
    PushStatus('Added ' + fileRefList.fileList.length.toString() + ' photo(s) to queue!');
    fileRefList.fileList.length = 0;
    buttonUpload.enabled = (arrayQueue.length > 0);
}

private function OnButtonRemoveClicked(e:Event):void
{
    for(var i:Number = 0; i < listFiles.selectedIndices.length; i++) {
        var toRemove:Number = listFiles.selectedIndices[i];
        //Alert.show(toRemove.toString());
        arrayQueue.splice(toRemove, 1);
    }
    listFiles.executeBindings();
    Alert.show('removecomplete:' + arrayQueue.length);
    PushStatus('Removed photos from queue.');
    buttonRemove.enabled = (listFiles.selectedItems.length > 0);
    buttonUpload.enabled = (arrayQueue.length > 0);
}

Ответы [ 5 ]

2 голосов
/ 31 марта 2009

Определенно было бы полезно знать две вещи:

  1. На какую версию ActionScript вы ориентируетесь?

  2. Судя по поведению вашего приложения, ошибка не возникает, когда пользователь удаляет элемент из списка файлов для загрузки. Больше похоже на проблему с вашей логикой, когда пользователь добавляет новый элемент в список. Есть ли шанс, что вы также можете разместить этот код?

UPDATE

Вместо: arrayQueue[arrayQueue.length]=lid

Попробуйте: arrayQueue.push(lid)

Это добавит новый элемент в конец массива и поместит его в это место.

ОБНОВЛЕНИЕ 2 :

Хорошо, немного покопался. Оказывается, что fileList не очищается при каждом открытии диалога (если вы не создаете новый экземпляр FileReferenceList каждый раз, когда пользователь выбирает новые файлы). Вам нужно вызвать splice () для fileList после добавления каждого файла в ваш массив.

Попробуйте что-то подобное в вашем методе AddFile () ...

for(var j:int=0; j < fileRefList.fileList.length; j++)
{
     arrayQueue.push(fileRefList.fileList[j]);
     fileRefList.fileList.splice(j, 1);
}

Это позволит поддерживать актуальный список файлов, а не сохранять предыдущие выборки.

0 голосов
/ 07 апреля 2009

Мне действительно нужно было бы увидеть весь класс, чтобы дать разносторонний ответ, но я бы написал метод для обработки удаления нескольких объектов из dataProvider и, возможно, назначения нового массива в качестве dataProvider для списка вместо игры с привязкой и использовать тот же список для продолжительности. Как я уже сказал, это, вероятно, неэффективно и потребует рассмотрения контекста вопроса, но это то, что я сделал бы, если бы у вас не было большой потребности в связывании в этих обстоятельствах)

/**
* Returns a new Array with the selected objects removed 
*/
private function removeSelected(selectedItems:Array):Array
{
    var returnArray:Array = []
    for each(var object:Object in this.arrayQueue)
    {
        if( selectedItems.indexOf(object)==-1 )
            returnArray.push( object )
    }
    return returnArray;
}
0 голосов
/ 06 апреля 2009

Вас может заинтересовать эта запись в блоге о том, что в языке Java отсутствуют надежные итераторы.

Язык программирования, о котором вы упомянули Javascript, - это не проблема, а концепция надежных итераторов, на которую я хотел обратить внимание (в действительности речь идет о C ++ как о языке программирования).

[Исследовательский документ] () о предоставлении надежных итераторов для среды ET ++ C ++ может по-прежнему быть полезным в решении вашей проблемы. Я уверен, что документ может дать вам необходимые идеи, как подойти к вашей проблеме.

0 голосов
/ 31 марта 2009

Вы хотите использовать listBox и listFiles для обозначения одного и того же?

Я перехожу здесь к конечности, потому что у меня нет большого опыта работы с JavaScript, но я бы сделал это так же, как сделал бы это на C, C ++ или Java: копирование оставшихся элементов массива в их новые местоположения.

Предполагая, что listFiles.selectedIndices отсортировано (и его содержимое является действительными индексами для dataArray), код будет выглядеть примерно так:

(ВНИМАНИЕ: следует непроверенный код.)

// Don't bother copying any elements below the first selected element.
var writeIndex = listFiles.selectedIndices[0];
var readIndex = listFiles.selectedIndices[0] + 1;
var selectionIndex = 1;
while(writeIndex < (dataArray.length - listFiles.selectedIndices.length)) {
  if (selectionIndex < listFiles.selectedIndices.length) {
    // If the read pointer is currently at a selected element,
    // then bump it up until it's past selected range.
    while(selectionIndex < listFiles.selectedIndices.length && 
          readIndex == listFiles.selectedIndices[selectionIndex]) {
      selectionIndex++;
      readIndex++;
    }
  }
  dataArray[writeIndex++] = dataArray[readIndex++];
}

// Remove the tail of the dataArray
if (writeIndex < dataArray.length) {
  dataArray.splice(writeIndex, dataArray.length - writeIndex);
}

РЕДАКТИРОВАТЬ 2009/04/04: Ваш алгоритм удаления по-прежнему страдает недостатком, заключающимся в том, что при удалении элементов в listFiles.selectedIndices вы нарушаете соответствие между индексами в arrayQueue и индексами в listFiles.selectedIndices.

Чтобы увидеть это, попробуйте добавить 3 файла, затем выполните «Выбрать все» и нажмите «Удалить». Это начнется с удаления первого файла в списке (индекс 0). Теперь то, что было , 2-й и 3-й файлы в списке имеют индексы 0 и 1. Следующее значение, взятое из listFiles.selectedIndices, равно 1 - но теперь, что было 3-м файл с индексом 1. Таким образом, предыдущий Файл № 3 выделяется из массива, оставляя прежний 2-й файл без удаления и с индексом 0. (Используя больше файлов, вы увидите, что эта реализация удаляет только все остальные файлы в массиве.)

Вот почему мой код JavaScript (выше) использует readIndex и writeIndex для копирования записей в массиве, пропуская readIndex по индексам, которые должны быть удалены. Этот алгоритм позволяет избежать проблемы потери соответствия между индексами массива. (Его нужно тщательно кодировать, чтобы защититься от различных краевых условий.) Я попробовал код JavaScript , аналогичный , который я написал выше; у меня это сработало.

Я подозреваю, что проблема в вашем исходном тестовом примере (удаление второго файла, а затем добавление другого) аналогична. Поскольку вы показали только часть своего кода, я не могу сказать, будут ли индексы массивов и данные в listFiles.selectedIndices, arrayQueue и fileRefList.fileList всегда соответствовать друг другу. (Но я подозреваю, что проблема в том, что они этого не делают.)

Кстати, даже если вы решите проблему с помощью splice(), настроив значения индекса массива соответствующим образом, это все равно алгоритм O (N 2 ) в общем случае. Алгоритм копирования массива O (N).

0 голосов
/ 31 марта 2009

Я вижу одну проблему. Выбранные индексы больше не действительны после того, как вы склеили первый элемент из массива. Но это должно быть проблемой только при удалении нескольких элементов одновременно.

Я думаю, нам нужно увидеть больше кода о том, как вы обрабатываете загрузку, прежде чем мы сможем понять, что происходит. Мне кажется, что вы держите ссылку на удаленный FileReference или что-то в этом роде. Описанная проблема возникает при загрузке нового файла, а не при удалении выбранного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...