Учитывая два массива, где один из них - это старый набор значений, а другой - новые значения, я хочу найти "diff" этих двух массивов, такие обновления для исходного массива могут быть представлены как:
enum CollectionChange<T: SequenceType> {
case Initial(T)
case Update(T, deletions: [Int], insertions: [Int], modifications: [Int])
}
Я пытаюсь создать более простую версию этого, где объект изменений строится на основе равенства объектов, а не индексов как RAC-MutableCollectionProperty
(для которого код здесь и какой может быть самый сложный бит кода, который я видел за время, никакая документация не помогает).
Также важно, чтобы этот проект мог наблюдать изменения в массиве на любом уровне детализации. Например, одномерный массив, ограничивающий T
до Equatable
, является относительно простым вариантом использования. Вы можете, как RAC-MutableCollectionProperty
создать какую-то таблицу, описывающую изменения, проверяя равенство на объектах. Однако, как только вы приступите к использованию двумерных массивов и глубже, это становится немного сложнее, потому что вам не только нужно различать элементы на самом низком уровне, но также описывать абзацы на уровне разделов. На практике, действительно, не больше 2D-массивов, но было бы неплохо иметь решение, которое работает независимо от глубины массива. Я не обязательно ищу решение (хотя это было бы фантастически), на самом деле просто любые указатели и решения высокого уровня о том, как подойти к этой проблеме.
Один из способов, с помощью которого я мог наблюдать несколько уровней массива, - написать функцию, которая работает на одномерных массивах, и построить свойство, которое:
let property: MutableCollectionProperty<MutableCollectionProperty<Int>>
где свойство проверяет, является ли его общий тип его собственным типом. Мне нужно будет изменить описание изменений на что-то ближе к
enum Changes<T> {
case Initial(T)
case Update(T, deletions: [NSIndexPath], insertions: [NSIndexPath], modifications: [NSIndexPath])
}
или, может быть, что-то вроде
enum Changes<T> {
case Initial(T)
case UpdateSections(sections: [T], deletions:[Int], insertions: [Int], modifications: [Int])
case UpdateIndexes(T, deletions: [Int], insertions: [Int], modifications: [Int])
}
Это только мои предварительные мысли, хотя я открыт для любого решения или предложения.
BOUNTY EDIT:
Награда будет вручена тому, кто может предоставить решение, которое дает следующие параметры:
- Пусть x и y - два быстрых массива
- оба массива типа
T: Equatable
- оба массива могут иметь любую глубину
- глубина x == глубина y
может быть сгенерирован набор изменений, где описывается набор изменений:
- какие элементы были удалены из x к y (по индексу)
- какие элементы были вставлены в y, не были в x (по индексу)
- какие элементы были перемещены из x к y (по индексу)
Изменения должны быть описаны только на самом низком уровне массива (не нужно беспокоиться о вставке и удалении более высоких сегментов, хотя вы действительно зарабатываете 300 репатов с этим), но изменяйте индексы должны указывать путь вложенного указателя.
Например, если массив представляет собой 3D-массив и объект в array[0][5][2]
был удален, результирующее изменение индекса должно быть массивом [0, 5, 2]
. Этот массив описывает одно удаление, и все удаления будут иметь тип [[Int]]
.
Edit:
Я удаляю требование наличия массивов любой глубины. Скажем, что это просто 1d массивы.