Reputation: 707
Say I have
arr1 = ["Tom","Harry","Patrick"]
arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"]
How can I remove the duplicate elements in arrays?
I want this output
arr2 = ["Miguel","Felipe","Mario"]
Upvotes: 3
Views: 4305
Reputation: 5250
Using includes()
is better because returns true or false, but unfortunately it is not supported by IE, see this. In case you want this working on IE too, you should use indexOf().
var arr1 = ["Tom","Harry","Patrick"]
var arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"]
arr2 = arr2.filter(e=>arr1.indexOf(e)<0)
console.log(arr2)
And filter is better because:
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Upvotes: 1
Reputation: 1857
If you have lodash, you can use the difference function directly.
_.difference(arr2, arr1)
will give the required output.
Edit: JSFiddle URL: https://jsfiddle.net/k3ynjq1m/3/
Upvotes: 1
Reputation: 908
So you want to remove elements from an array (if they exist) based from another array. Ok, let see... I have a component that implement a function with a similar logic:
let criteriaArr = ["Tom", "Harry", "Patrick"];
let arrToFilter = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"];
let filteredArray = arrToFilter.filter(e => criteriaArr.indexOf(e) < 0);
console.log(filteredArray);
So what filter does is: Returns the elements of an array that meet the condition specified in a callback function.
what the callback function does is: for each element from arrToFilter, if that element does not exit in criteriaArr then keep it otherwise go to the next element.
Here is the function:
removeElems(arrToFilter: Array<any>): Array<any> {
let filteredArray = arrToFilter.filter(e => this._criteriaArr.indexOf(e) < 0);
return filteredArray;
}
this._criteriaArr is a private property with default value: private _criteriaArr = ["Tom","Harry","Patrick"]
Or, you can do it this way:
removeElems(arrToFilter: Array<any>, criteriaArr: Array<any>): Array<any> {
let filteredArray = arrToFilter.filter(e => criteriaArr.indexOf(e) < 0);
return filteredArray;
}
handle it with two array.
have fun ! :)
Upvotes: 0
Reputation: 1
So the way I see it there are multiple ways to achieve what you're looking for,
filter
and include
like some mentioned above me -
It will work but I don't know how efficient that will be as you are using filter to iterate on arr2 and then for each element you iterate on arr1 to see if there's matching case, I don't know how familiar you are with algorithm analysis but it's O(N power 2) which is not very time efficient, means quickly as arr1 or arr2 will grow it will take much longer for your function to run, if you do go with that option please use sort()
first so you might save time and be more efficient.See Example:
let namesToRemove = ["Tom", "Harry", "Patrick"].sort()
let names = ["Miguel", "Harry", "Patrick", "Felipe", "Mario", "Tom"].sort()
let lastNameToRemove = namesToRemove[namesToRemove.length - 1]
names = names.filter((name) => {
if (name[0] > lastNameToRemove[0]) {
return true
}
return !namesToRemove.includes(name)
})
console.log(names)
Keep in mind that if you will use for loop
and splice()
you can just break and it will be even more efficient.
Map
- You can iterate once on your first array and create a map in JS which is just using an object notation and once on your names array and check if there is a match, you can improve that using sort()
and other improvement but the idea is, see below example.See Example:
let namesToRemove = ["Tom", "Harry", "Patrick"]
let names = ["Miguel", "Harry", "Patrick", "Felipe", "Mario", "Tom"]
let namesToRemoveMap = {}
for (name of namesToRemove) {
namesToRemoveMap[name] = true
}
names = names.filter((name) => !namesToRemoveMap[name])
console.log(names)
Of course either way you choose I would include some more defensive checks, like if the arrays have value in them etc...
Hope I could explain myself clear, let me know if you need more help or if you have any question.
Upvotes: 0
Reputation: 16384
I think that the best way will be to use filter()
array method, iterate through the target array (it's arr2
in this case), and exclude duplicates via !arr1.includes(currentItem)
. This construction lets you know, does arr1
contain current item of iteration:
const arr1 = ["Tom","Harry","Patrick"];
const arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"];
const result = arr2.filter(d => !arr1.includes(d));
console.log(result);
Upvotes: 1
Reputation: 8868
for(var i = 0 ; i<this.arr1.length; i++) {
for(var j = 0 ; j<this.arr2.length; j++) {
if(this.arr1[i] === this.arr2[j]) {
this.arr1.splice(i, 1);
this.arr2.splice(j, 1);
i--;
j--;
}
}
}
this.arr2 = this.arr1.concat(this.arr2);
console.log(this.arr2)
here's a working code (your exemple): https://stackblitz.com/edit/angular-yzte87
Upvotes: 0
Reputation: 276239
Use filter
combined with includes
. Example:
let arr1 = ["Tom","Harry","Patrick"]
let arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"]
arr2 = arr2.filter(x=>!arr1.includes(x))
console.log(arr2)
Upvotes: 3
Reputation: 5254
I think you should keep a map and add elements to that map.
if element exists in map, then that is duplicate else add it to map.
The way you can store your duplicates is storing their value in another list. That is up to you.
Once you know your duplicates, duplicate it from the list.
This is O(n) complexity, and O(n) space complexity.
Upvotes: 0
Reputation: 241
Using regular js, you can use a nested for loop:
for (var i in arr2) {
var duplicate = false;
for (var i2 in arr1) {
if (arr2[i] == arr1.[i2]) {
duplicate = true;
}
}
if (duplicate) {
arr2.splice(i, 1);
}
}
Upvotes: 0