Exclude duplicates from array [duplicate] - javascript

This question already has answers here:
Remove duplicate values from JS array [duplicate]
(54 answers)
Completely removing duplicate items from an array
(11 answers)
remove all elements that occur more than once from array [duplicate]
(5 answers)
Closed 2 years ago.
I am trying to exclude duplicate numbers from the array. For example: if I filter an array of [1,2,2,3,5,5] the output should be [1,3].
function unique(arr) {
let sortArr = arr.sort()
let res = []
for (let i = 0; i < arr.length; i++) {
if (sortArr[i] != sortArr[i + 1]) {
res.push(sortArr[i])
}
}
return res
}
console.log(unique([1, 2, 2, 3, 5, 5]))
I was trying not to add duplicate numbers into an array, but instead of [1,3] I am getting [1,2,3,5]

The easiest tweak would be to check that both the next element and the previous element don't equal the current element:
function unique(arr) {
let sortArr = arr.sort()
let res = []
for (let i = 0; i < arr.length; i++) {
if (sortArr[i] != sortArr[i + 1] && sortArr[i] !== sortArr[i - 1]) {
res.push(sortArr[i])
}
}
return res
}
console.log(unique([1, 2, 2, 3, 5, 5]))
But .sort has a computational complexity of O(n log n). This can be done in O(n) time by counting up the number of results in an object instead:
function unique(arr) {
const ones = new Set();
const dupes = new Set();
for (const item of arr) {
if (dupes.has(item)) continue;
if (ones.has(item)) {
dupes.add(item);
ones.delete(item);
} else ones.add(item);
}
return [...ones];
}
console.log(unique([1, 2, 2, 3, 5, 5]))

Using Array.reduce, you can get the duplicated count of each item and based on that data, can get the non-duplicated values only as follows.
function unique(arr) {
const groupBy = arr.reduce((acc, cur) => {
acc[cur] ? acc[cur] ++ : acc[cur] = 1;
return acc;
}, {});
return Object.entries(groupBy)
.filter(([key, value]) => value === 1)
.map(([key]) => +key);
}
console.log(unique([1, 2, 2, 3, 5, 5]));

Count the number of values and returns only those that are equal to 1
function unique(array) {
var map = new Map();
array.forEach(a => map.set(a, (map.get(a) || 0) + 1));
return array.filter(a => map.get(a) === 1);
}
console.log(unique([1, 2, 2, 3, 5, 5]));

Related

Sorting an Array that consists of numbers, BUT can include strings

I am facing an issue where I get results from API(mainly array of numbers), but if the devs make mistake and leave the field empty I will get empty string ("").
I am trying to sort this array in an ascending order and move the empty strings in the back of the Array, like that:
let arr = [3, 4, "", 1, 5, 2] // Example Array from api
This array, when modified should become:
let res = [1, 2, 3, 4, 5, ""]
I tried using the arr.sort() method, but the results look like that:
let res = ["",1 ,2 ,3 ,4 ,5]
For some reason when the element is string, the sort method puts it in the front, not in the end like it does with undefined or null for example.
Method 1
let arr = [3, 4, "", 1, 5, 2];
const res = arr.sort((a, b) => {
if (typeof a === 'string') {
return 1;
} else if (typeof b === 'string') {
return -1;
} else {
return a - b;
}
}
);
console.log(res)
Output:
[ 1, 2, 3, 4, 5, '' ]
Method 2
const res = (arr) => {
let newArr = [];
let strArr = [];
for (let i = 0; i < arr.length; i++) {
if (typeof arr[i] === 'string') {
strArr.push(arr[i]);
} else {
newArr.push(arr[i]);
}
}
return newArr.concat(strArr);
}
console.log(res(arr));

Flatten an array [duplicate]

This question already has answers here:
Flatten array of multiple nested arrays without recursion - javascript
(9 answers)
Closed last year.
I want to flatten an array with javascript but without recurssion and without prebuilt function.
This is the code but it dose not flatten the whole array and i want to know what is wrong with my code
input : [1, [2], [3,8, [[4]],9],[5,6]]
output : [1, 2, 3, 8, 5, 6]
Code :
flat = function(array) {
const output = []
for (let i = 0; i < array.length; i++) {
if (typeof array[i] == 'number') {
output.push(array[i])
} else {
let arr = array[i]
let n = 0
while (n < arr.length) {
if (typeof arr[n] == 'number') {
output.push(arr[n])
n++
} else {
arr = arr[n]
n--
console.log(arr, n);
}
}
}
}
return output
}
It's possible to do, but it involves managing a stack yourself, manually:
const input = [1, [2], [3, 8, [[4]], 9], [5, 6]];
const result = [];
const stack = [{current: input, pos: 0}];
while (stack.length > 0) {
let {current, pos} = stack.pop();
if (pos < current.length) {
let item = current[pos++];
stack.push({current, pos});
if (Array.isArray(item)) {
stack.push({current: item, pos: 0});
} else {
result.push(item);
}
}
}
console.log(result);
This is what a recursive approach would do in the background, more or less. If your concern about recursion was that you don't like/understand it, not sure that you will find this one more likeable.

The values of the array "b" has to be removed from the array "a" [duplicate]

This question already has answers here:
How to get the difference between two arrays in JavaScript?
(84 answers)
Closed 2 years ago.
I wrote the function to accomplish what was asked, but was wondering if there was a better and nicer way to do that?
function arrayDiff(a, b) {
let myArr = [];
for (let i = 0; i < a.length; i++) {
if (a[i] == b[0] || a[i] == b[1]) {
continue;
} else {
myArr.push(a[i]);
}
}
return myArr;
}
arrayDiff([1,2,3], [2,3]) //returns [1]
What if the length of the array "b" was more than just two elements, for example 5, how could I write a better code?
You could take a single comparison by using Array#includes.
function arrayDiff(a, b) {
let myArr = [];
for (let i = 0; i < a.length; i++) {
if (b.includes(a[i])) continue;
myArr.push(a[i]);
}
return myArr;
}
console.log(arrayDiff([1, 2, 3], [2, 3])); // [1]
Another faster approach takes an object with O(1) fo looking for the value of b, for example with a Set.
function arrayDiff(a, b) {
let myArr = [],
excluding = new Set(b);
for (let i = 0; i < a.length; i++) {
if (excluding.has(a[i])) continue;
myArr.push(a[i]);
}
return myArr;
}
console.log(arrayDiff([1, 2, 3], [2, 3])); // [1]
const a = [1,2,3], b = [2,3]
let result = a.filter(n=>!b.includes(n))
console.log(result)
You can loop the second array and get the index of the item from the first array. Then use splice to remove the item from first array
function arrayDiff(a, b) {
let z = a;
b.forEach((item) => {
const getIndx = z.indexOf(item);
if (getIndx !== -1) {
z.splice(getIndx, 1)
}
});
return z;
}
console.log(arrayDiff([1, 2, 3], [2, 3]))

How to get only values with not duplicated from an array [duplicate]

This question already has answers here:
Javascript remove all occurrence of duplicate element, leaving the only one that is unique
(10 answers)
Closed 3 years ago.
Here is an array : [2,2,3,3,5,7,9,9]
from this array, i needs the values not it doesn't have an duplicate. how to get it?
const onlyUniqueWithoutDup = array.filter((item) => !item.indexOf(array))
looking the result as : [5,7];
any help?
You can use:
const array = [2,2,3,3,5,7,9,9];
const result = array.filter((item, index, arr) => (arr.lastIndexOf(item) == arr.indexOf(item)));
console.log(result);
Create an object where the keys will be the element from this array and then the value will the number of repetition. Then iterate this object and get the keys where value is only 1
let data = [2, 2, 3, 3, 5, 7, 9, 9];
let newData = data.reduce((acc, curr) => {
if (acc[curr]) {
acc[curr] += 1;
} else {
acc[curr] = 1
}
return acc;
}, {});
let nonDup = [];
for (let keys in newData) {
if (newData[keys] === 1) {
nonDup.push(keys)
}
}
console.log(nonDup)

How to get the sum of all duplicates in an array?

I am trying to calculate the sum of all duplicates in an array. For example:
duplicate([1,1,2,3,3]) --> should return 8.
I have written the following function to calculate the sum of duplicates in an array using JavaScript. Currently it is returning an array with duplicates one less than what they are present in the array.
function duplicate(arr) {
var sum = 0;
arr.sort();
var stack = [];
for(var i = 0; i < arr.length; i++){
if (arr[i] === arr[i+1]) {
stack.push(arr[i])
}
}
return stack;
}
console.log(duplicate([1,2,1,2,2,3,3]))
This is returning [ 1, 2, 2, 3 ]
How do I get the correct array and calculate the correct sum? I have to use Object for that?
To make the logic easier, you might filter out the non-duplicates by checking whether their indexOf in the array is equal to their lastIndexOf in the array:
function duplicate(arr) {
const duplicates = arr.filter(elm => arr.indexOf(elm) !== arr.lastIndexOf(elm));
return duplicates.reduce((a, b) => a + b);
}
console.log(duplicate([1,1,2,3,3])); // --> should return 8.
console.log(duplicate([1,2,1,2,2,3,3]));
Initially create an object where the keys will be the integer and their value will be the number of occurrence. Then if the number of occurrence is more than 1 , multiply the number with number of occurrence.
function duplicate(arr) {
let dupVal = 0;
let k = arr.reduce((acc, curr, index) => {
if (acc[curr] === undefined) {
acc[curr] = 1
} else {
acc[curr] += 1;
}
return acc
}, {});
for (let keys in k) {
if (k[keys] > 1) {
dupVal += parseInt(keys, 10) * k[keys]
}
}
return dupVal;
}
console.log(duplicate([1, 2, 1, 2, 2, 3, 3]))
Try This one
const arr = [1,1,2,3,3]
let dup = arr.filter((value, index)=>{
// creating a copy of main array
let copyarr = [].concat(arr)
// removing present value
copyarr.splice(index,1)
// after removing present value, if you still
// get the value in copied array that means
// it has duplicates
if(copyarr.indexOf(value)>-1){
return true
}
return false
})
// now add it using reduce
let sum = dup.reduce((acc, value)=> acc+value,0)
console.log(sum)
Copy above code and paste into chrome devTool. You will get the answer.
The problem is that you are matching value with immediate next value in array, in array that is sorted already it will work, but not on unsorted one. So try to sort the array first and then run your code.
Edit :
Looks like sorting is added in code,
But another condition => if there is number that is repeated more than twice it should be handled and only appear once in stack, if that is required.
This will : console.log(duplicate([1,2,1,2,2,3,3]))
Result this : [1,2,3]
function duplicate(arr) {
var sum = 0;
arr.sort();
var stack = [];
for(var i = 0; i < arr.length; i++){
if (arr[i] === arr[i+1]) {
if(stack.length == 0 || (arr[i] != stack[stack.length-1])){
stack.push(arr[i])
}
}
}
return stack;
}
you can use JS Array.reduce method to accomplish your requirement in a shorter way
function sumDplicates(arr) {
return arr.reduce(function(tot, val, index, _arr) {
if (_arr.lastIndexOf(val) > index || _arr.indexOf(val) != index)
return tot + val;
return tot
}, 0)
}
console.log(sumDplicates([1, 1, 2, 3, 3]));
console.log(sumDplicates([1, 2, 1, 2, 2, 3, 3]));
You can pursue your original sorting approach with a slight modification:
if (arr[i] === arr[i + 1] || arr[i] === arr[i - 1])
That is, check if the previous or the next element in the sorted array is equal to the current element for it to qualify as a duplicate.
The following solution accomplishes this with filter and reduce:
function duplicate(array) {
return array
.sort((a, b) => a - b)
.filter((a, i, arr) => (arr[i] === arr[i + 1] || arr[i] === arr[i - 1]))
.reduce((a, b) => a + b, 0);
}
console.log(duplicate([1, 1, 2, 3, 3]));
console.log(duplicate([1, 2, 1, 2, 3, 3]));
Array.reduce() and Array.lastIndexOf() will simply solve your problem.
function sum(arr)
{
return arr.reduce(function(sum, item){
return arr.lastIndexOf(item)!==arr.indexOf(item) ? sum+=item : sum;
},0)
}
console.log(sum([1,1,2,3,3]));
console.log(sum([1,2,3,4]));
console.log(sum([1,2,2,3,4]));
console.log(sum([1,1,2,2,3,3,4,4]));
Though I don't know much about JavaScript, If I were you, I would have simply kept a temporary array, which copies all the duplicate variables and then use that array for sum.
Also, if you want to add the particular number as many times as it appears, I will suggest creating a table like the one in sparse matrices
and then referring to it during addition.
This logic, though not space efficient, is very easy to implement.
Here is an approach with a single Array.reduce and nothing else. No Array.indexOf or Array.lastIndexOf. Although it might not be as concise it does not traverse the array looking for indexes multiple times nor does any Array.filter:
const sumDubs = arr => arr.reduce((r,c) => {
if(r[c]) {
r[c] += 1
r.sum += r[c] > 2 ? (r[c]*c) - ((r[c]-1)*c) : r[c]*c
} else r[c] = 1
return r
}, { sum: 0 }).sum
console.log(sumDubs([1, 1, 2, 3, 3])) // 8
console.log(sumDubs([1, 2, 1, 2, 2, 3, 3])) // 14
console.log(sumDubs([1, 2, 1, 2, 2, 3, 3, 3, 1, 2, 4, 4])) // 28
The idea is to keep track of the on-going sum via a property in the accumulator of the Array.reduce and simply keep calculating the sum based on which number is duplicated and more importantly how many times.

Categories

Resources