Find item that changed its position in array

82 views Asked by At

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.

1

There are 1 answers

0
PeterKA On

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