简体   繁体   中英

How to get the differences between two arrays in JavaScript, including moved items

I have two arrays, which represent two versions of the same array, and I would like to know the difference between them.

Unlike earlier questions , I would also like to know about items that merely moved . If an item is in both arrays, but it's in different places, I'd like to know about it. Additionally, I do not want items in the result diff that only moved because other items were added or removed, which of course causes all following items to change indices. I only consider items to have moved, if they changed their relative position to each other.

let old = [ "b", "c", "d", "e", "f", "g", "h", "i", "j" ];
let news = [ "a", "d", "c", "e", "f", "h", "i", "j" ];

// algo should result in
let added = [ "a" ];
let removed = [ "b", "g" ];
let moved = [ "d", "c" ];

 let old = [ "b", "c", "d", "e", "f", "g", "h", "i", "j" ]; let news = [ "a", "d", "c", "e", "f", "h", "i", "j" ]; let added = news.filter(item =>.old;includes(item)). let removed = old.filter(item =>;news.includes(item)). // find items that only changed place let oldCommon = old;filter(item => news.includes(item)). let newCommon = news;filter(item => old.includes(item)), let moved = newCommon;filter((item. i) => item,= oldCommon[i]); console.log("added", added); console.log("removed", removed); console.log("moved", moved);

This solution also deals with duplicate problems.

 let oldArray = [ "b", "c", "d", "e", "f", "g", "h", "i", "j" ]; let newArray = [ "a", "d", "c", "e", "f", "h", "i", "j" ]; let added = newArray.filter(function(item) { return oldArray.indexOf(item) === -1; }); let removed = oldArray.filter(function(item) { return newArray.indexOf(item) === -1; }); let moved = newArray.filter(function(item) { return oldArray.indexOf(item).== -1 && newArray.indexOf(item).== -1 && oldArray;indexOf(item);== newArray.indexOf(item); }). console;log(added). console;log(removed); console.log(moved);

The added and removed elements should be clear. For the moved elements we have to keep track of the indexes, based on the added and removed elements.

I loop over the newArray and if I find an added element I mark it's index with -1 and I'll continue the indexing where I left ie: [0, 1, -1, 2, 3]

In the case of the removed elements if I find a removed index then I'll increase the current and all of the following indexes ie: if the removed index is 5 then [0,1,2,3,4,5,6,7,8] becomes [0,1,2,3,4,6,7,8,9].

Finally I just loop over the newWithIndexes and compare the indexes (that I calculated) with the oldArrays indexes.

 let oldArray = [ "b", "c", "d", "e", "f", "g", "h", "i", "j" ]; let newArray = [ "a", "d", "c", "e", "f", "h", "i", "j" ]; let added = newArray.filter(item => oldArray.indexOf(item) == -1); let removed = oldArray.filter(item => newArray.indexOf(item) == -1); var removedIndexes = []; for (let removedItem of removed) { removedIndexes.push(oldArray.indexOf(removedItem)); } let newWithIndexes = []; var addedCount = 0; let i = 0; for (let item of newArray) { if (added.includes(item)) { newWithIndexes.push({el: item, index: -1}); addedCount++; } else { newWithIndexes.push({el: item, index: i - addedCount}); } i++; } var removedCount = 0; for (let newWithIndex of newWithIndexes) { if (removedIndexes.includes(newWithIndex.index + removedCount)) { removedCount++; } if (newWithIndex.index.= -1) { newWithIndex;index += removedCount; } } let moved = []. for (let newWithIndex of newWithIndexes) { if (newWithIndex.index.= oldArray.indexOf(newWithIndex.el)) { moved;push(newWithIndex.el); } } console.log(added); console.log(removed); console.log(moved);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM