I created a script in javascript which should track all changes between 2 arrays of strings. For ex: if element was added or removed comparing with the first array.
const initial = ['test', 'color'];
const changed = ['5'];
const checkArrDiff = (initialArr, changedArr) => {
const newElements = [];
const removedElements = [];
const getDiff = changedArr.reduce((acc, item, idx) => {
if (!initialArr.includes(item)) {
newElements.push(item)
acc.new = newElements
}
if (!changedArr.includes(initialArr[idx])) {
removedElements.push(initialArr[idx])
acc.removed = removedElements
}
return acc;
}, {})
return getDiff;
}
console.log(checkArrDiff(initial, changed))
In the case above I expect the next result:
{
"new": [
"5"
],
"removed": [
"test", "color"
]
}
At the moment I get the wrong result. Who can help to fix the code?
CodePudding user response:
UPDATED ANSWER
For example we have two arrays arr1
and arr2
.
arr1 = ["a", "b", "c"];
arr2 = ["b", "d"];
In above example arrays I have removed a,c
and added d
, but in my old code it will not give exact result what we expected, because when we remove a
than next element b
will move to 0
index so my old code will assume b
as new element, but is just had changed it's index.
Here I have solved that by inserting undefined
value at unmatched value position with spice
function.
Now it will detect duplicated and real value. please recheck with multiple example arrays.
// new example to check does it work well or not
let initial = ["a", "b", "c"];
let changed = ["b", "d"];
console.log(getDifference(initial, changed));
// main function
function getDifference(array1, array2) {
let result = {removed:[], new:[]};
array1.filter((item, index) => item !== array2[index] ? (result.removed.push(item) && array2.splice(index, 0, undefined)) : null);
array2.filter((item, index) => (item !== array1[index] && item !== undefined) ? (result.new.push(item)) : null);
return result;
}
OLD ANSWER
It will give accurate result by matching both index number and value.
const initial = ['test', 'color'];
const changed = ['5'];
console.log(getDifference(initial, changed));
function getDifference(array1, array2) {
let result = {removed:[], new:[]};
array1.filter((item, index) => item !== array2[index] ? (result.removed.push(item)) : null);
array2.filter((item, index) => item !== array1[index] ? (result.new.push(item)) : null);
return result;
}
CodePudding user response:
The problem is you iterate over the changed array which has 1 index while you try to check 2 indexes of the initial array.
You can simplify your logic though. I think this is what you want.
With just 2 array filter calls you can define the removed and new elements.
const initial = ['test', 'color', 'both'];
const changed = ['5', 'both'];
const checkArrDiff = (initialArr, changedArr) => {
return {
new: changed.filter((item) => !initial.includes(item)),
removed: initial.filter((item) => !changed.includes(item))
}
}
console.log(checkArrDiff(initial, changed))
CodePudding user response:
Well, I would use a simple loop for that and not a reduce for reasons that jabaa pointed out
function checkArrDiff(before,after){
var toReturn={new:[],removed:[]}
var extras={new:[],removed:[]}
//useless check removed by sensible suggestion by jabaa
if(before.length<after.length){ //definitely new things
for(let i=before.length;i<after.length;i ){
extras.new.push(after[i])
}
}
else if(after.length<before.length){ //definitely removed things
for(let i=after.length;i<before.length;i ){
extras.removed.push(before[i])
}
}
var length=after.length>before.length?before.length:after.length //lowest length between the 2
for(let i=0;i<length;i ){
if(before[i]!=after[i]){
toReturn.new.push(after[i])
toReturn.removed.push(before[i])
}
}
toReturn.new.push(...extras.new)
toReturn.removed.push(...extras.removed)
return toReturn
}
//example
console.log(checkArrDiff(['test', 'color'],['5']))
CodePudding user response:
Here is my solution based on @Mark Baijens solution
/**
* @param initialArr {string[]}
* @param changedArr {string[]}
* @returns {{
* newEntry: string[]
* removedEntry: string[]
* }}
*/
const checkArrDiff = (initialArr, changedArr) => {
let newEntry = changedArr.filter((item) => !initialArr.includes(item));
let removedEntry = initialArr.filter((item) => !changedArr.includes(item));
if (!(newEntry.length && removedEntry.length)){
const difference = Math.abs(initialArr.length - changedArr.length);
if (initialArr.length - changedArr.length === 0){
return {
newEntry: [],
removedEntry: []
}
} else if (initialArr.length - changedArr.length > 0){
for (let i = 0; i < difference; i ) {
newEntry.push(initialArr[0])
}
} else {
for (let i = 0; i < difference; i ) {
removedEntry.push(initialArr[0])
}
}
}
return {
newEntry,
removedEntry
}
}
console.log(checkArrDiff(['one', 'two', 'both'], ['three', 'both']))
console.log(checkArrDiff(['both', 'both', 'both'], ['both', 'both']))
console.log(checkArrDiff(['both', 'both', 'both'], ['both', 'both', 'both', 'both']))