Reputation: 1580
I have an array that represents html items that can be dragged and therefore the order can be changed. Let's say before drag'n'drop event there is an array:
let oldArr =
[{id: 'id1'}, {id: 'id2'}, {id: 'id3'}, {id: 'id4'}, {id: 'id5'}, {id: 'id6'}]
and after dragging and reordering single item (let's say dragging item id5
to position (index) 2 the array will be:
let newArr =
[{id: 'id1'}, {id: 'id2'}, {id: 'id5'}, {id: 'id3'}, {id: 'id4'}, {id: 'id6'}]
How could it be decided which item was dragged to new position by comparing the old and the new aray?
Please note that if only 2 next-to-each-other items are changed, then it is impossible to decide which one of those 2 items was actually dragged - in this case it doesn't matter which one item of those two will be the result.
Upvotes: 0
Views: 105
Reputation: 24638
Use elements before and after a target element (neighbors) to determine which element(s) has(have) moved. You can refine the logic to more closely suit your situation:
const
oldArr = [{id: 'id1'}, {id: 'id2'}, {id: 'id3'}, {id: 'id4'}, {id: 'id5'}, {id: 'id6'}],
newArr = [{id: 'id1'}, {id: 'id2'}, {id: 'id5'}, {id: 'id3'}, {id: 'id4'}, {id: 'id6'}],
//Now get old neighbors (oldn) and new neighbors (newn)
oldn = oldArr.reduce((o,{id},i,a) => ({...o, [id]:[(i === 0) ? '-' : a[i-1].id, (i === a.length - 1) ? '-' : a[i+1].id]}), {}),
newn = newArr.reduce((o,{id},i,a) => ({...o, [id]:[(i === 0) ? '-' : a[i-1].id, (i === a.length - 1) ? '-' : a[i+1].id]}), {}),
//Now check which has changed both neighbors. The logic can be refined.
whichmoved = oldArr.filter(({id}) => oldn[id].every(n => !newn[id].includes(n)));
console.log( oldn, newn, '\n\n\nMoved:\n', whichmoved );
Upvotes: 1