Related
I know there are multiple ways to remove duplicates from arrays in javascript, the one i use is
let originalArray = [1, 2, 3, 4, 1, 2, 3, 4]
let uniqueArray = array => [...new Set(array)]
console.log(uniqueArray) -> [1, 2, 3, 4]
what i want is something similar but instead of removing the duplicates, to replace it with whatever string or number i want, like this
console.log(uniqueArray) -> [1, 2, 3, 4, "-", "-", "-", "-"]
this has to work with any order, like
[1, 2, 3, 3, 4, 5, 7, 1, 6]
result -> [1, 2, 3, "-", 4, 5, 7, "-", 6]
i tested this solution
const arr = [1, 2, 3, 1, 2, 3, 2, 2, 3, 4, 5, 5, 12, 1, 23, 4, 1];
const deleteAndInsert = uniqueList => {
const creds = uniqueList.reduce((acc, val, ind, array) => {
let { count, res } = acc;
if (array.lastIndexOf(val) === ind) {
res.push(val);
} else {
count++;
};
return { res, count };
}, { count: 0, res: [] });
const { res, count } = creds;
return res.concat(" ".repeat(count).split(" "));
};
console.log(deleteAndInsert(arr));
but only adds it at the end of the uniques, and also, only works with numbers
i want it to work with strings too, like dates as an example
["2021-02-22", "2021-02-23", "2021-02-22", "2021-02-28"]
You could still use a Set and check if the value is in the set.
const
unique = array => array.map((s => v => !s.has(v) && s.add(v) ? v : '-')(new Set));
console.log(...unique([1, 2, 3, 4, 1, 2, 3, 4]));
console.log(...unique([1, 2, 3, 3, 4, 5, 7, 1, 6]));
Just create new Array, use 1 set to control which element appeared, if one element appears more than 1, push new one character like '-'
let originalArray = [1, 2, 3, 4, 1, 2, 3, 4];
let newArray = [];
let set = new Set();
for (let i = 0; i < originalArray.length; i++) {
if(!set.has(originalArray[i])) {
newArray.push(originalArray[i]);
set.add(originalArray[i]);
} else {
newArray.push('-');
}
}
console.log(newArray);
You could do it with reduce
const dashDupes = array => array.reduce((acc, e) => {
if(acc.idx[e])
acc.arr.push('-')
else{
acc.arr.push(e);
}
acc.idx[e] = true;
return acc;
},{idx:{},arr:[]}).arr
console.log(...dashDupes([1, 2, 3, 4, 1, 2, 3, 4]))
console.log(...dashDupes([1, 2, 3, 3, 4, 5, 7, 1, 6]))
This is a very simple approach to the problem:
function uniqueReplace(arr, rep) {
let res = [];
for (x of arr) {
res.push(res.includes(x) ? rep : x);
}
return res;
}
console.log(...uniqueReplace([1, 2, 3, 4, 1, 2, 3, 4], '-'));
console.log(...uniqueReplace([1, 2, 3, 3, 4, 5, 7, 1, 6], '-'));
I have an object with number values assigned to keys
obj1 = {a : 10
b : 5
c : 6 }
and I want to decrement each number to zero so that each key has all values in that range, i.e:
obj2 = {a : 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
b : 5, 4, 3, 2, 1, 0
c : 6, 5, 4, 3, 2, 1, 0}
ive tried .map, .apply, and several other attempts at iteration. how can I accomplish this?
You can create an array of object entries, and then use reduce() to create the result object:
const obj1 = {
a: 10,
b: 5,
c: 6
};
const obj2 = Object.entries(obj1).reduce((a, [k, v]) => ({
...a,
[k]: Array(v + 1).fill(0).map(_ => v--)
}), {});
console.log(obj2);
Here is a much simpler solution:
const obj1 = { a: 5, b: 6, c: 3 };
let obj2;
Object.keys(obj1)
.forEach((key) => {
const size = obj1[key];
obj2[key] = new Array(size + 1)
.fill(0)
.map((val, index) => size - index);
});
console.log(obj2);
The result thus obtained will be in this format:
{
a: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
b: [5, 4, 3, 2, 1, 0],
c: [6, 5, 4, 3, 2, 1, 0],
}
let obj1 = {
a: 10,
b: 5,
c: 6,
};
let obj2 = Object.fromEntries(Object.entries(obj1).map(([k, v]) => [k, [...Array(v)].map((_, i) => v - i)]));
console.log(obj2);
let obj1 = {a : 10, b : 5, c : 6}
let res = Object.entries(obj1).reduce((acc, cur) => {
return Object.assign(acc, {[cur[0]]: Array.from(Array(cur[1]+1).keys()).reverse().join()})
}, {})
console.log(res)
Having an array of numbers setOfNumbers = [0, 3, 3, 2, 7, 1, -2, 9] I'd like to sort this set to have the smallest numbers on the end and beginning and the biggest in the center of the sorted set like this sortedSetNumbers = [0, 2, 3, 9, 7, 3, 1, -2].
const setOfNumbers = [0, 3, 3, 2, 7, 1, -2, 9];
const result = [0, 2, 3, 9, 7, 3, 1, -2];
function sortNormal(a, b) {
return true; // Please, change this line
}
const sortedSetNumbers = setOfNumbers.sort((a, b) => sortNormal(a, b));
if (sortedSetNumbers === result) {
console.info('Succeeded Normal Distributed');
} else {
console.warn('Failed Normal Distribution');
}
console.log(sortedSetNumbers);
I am sure it is possible to sort these numbers with the method Array.prototype.sort(), but how should this sorting function look like?
EDIT: The solution does not have to be solved with .sort(). That was only an idea.
This might be the most naive way to do it, but isn't it simply left, right, left, right... after sorting?
const input = [0, 3, 3, 2, 7, 1, -2, 9];
const expected = [0, 2, 3, 9, 7, 3, 1, -2];
const sorted = input.slice().sort();
const output = [];
let side = true;
while (sorted.length) {
output[side ? 'unshift' : 'push'](sorted.pop());
side = !side;
}
console.log(expected.join());
console.log(output.join());
Or simply:
const input = [0, 3, 3, 2, 7, 1, -2, 9];
const output = input.slice().sort().reduceRight((acc, val, i) => {
return i % 2 === 0 ? [...acc, val] : [val, ...acc];
}, []);
console.log(output.join());
A slightly different approach is to sort the array ascending.
Get another array of the indices and sort the odds into the first half asending and the even values to the end descending with a inverted butterfly shuffle.
Then map the sorted array by taking the value of the sorted indices.
[-2, 0, 1, 2, 3, 3, 7, 9] // sorted array
[ 1, 3, 5, 7, 6, 4, 2, 0] // sorted indices
[ 0, 2, 3, 9, 7, 3, 1, -2] // rebuild sorted array
var array = [0, 3, 3, 2, 7, 1, -2, 9].sort((a, b) => a - b);
array = Array
.from(array, (_, i) => i)
.sort((a, b) => b % 2 - a % 2 || (a % 2 ? a - b : b - a))
.map(i => array[i]);
console.log(array);
This solution is not really elegant, but it does it's job.
const setOfNumbers = [0, 3, 3, 2, 7, 1, -2, 9];
const alternation = alternate();
const sortedSetNumbers = sortNormal(setOfNumbers);
function sortNormal(start) {
const result = [];
const interim = start.sort((a, b) => {
return b - a;
});
interim.map(n => {
if (alternation.next().value) {
result.splice(0, 0, n);
} else {
result.splice(result.length, 0, n);
}
});
return result;
}
function* alternate() {
let i = true;
while (true) {
yield i;
i = !i;
}
}
console.log(sortedSetNumbers);
What I'm trying to do is find how many times an array elements repeats itself in array, push the element along with the number of repeats it has in an object and after that delete the element and all its duplicates.
At the moment I have this function :
function getDuplicates(arr) {
let lastIndex = null;
let obj = {};
for ( let i = 0; i < arr.length; i++ ) {
lastIndex = arr.lastIndexOf(arr[i]);
obj[arr[i]] = lastIndex + 1;
arr.splice(0, lastIndex + 1 );
}
console.log(obj);
}
getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
which logs : { '1': 4, '2': 2, '3': 4, '5': 5 }
It works great for the first 3 numbers ( 1,2 and 3 ) but 4 doesnt show up, 5 is messed up and 6 doesnt show due to lastIndex +1. Am I missing something or is there a better way to do this ?
Thank you.
You can simplify a lot the logic. Just an object to count and an if statement to increment values or define as 1 if it wasn't defined.
function countDuplicates(arr) {
// Contains a pair of values an instances.
var counting = {};
// Iterate array: check if already counted. If yes, increment, if not define as 1.
for (el of arr) (counting[el]) ? counting[el]++ : counting[el] = 1;
console.log(counting);
return counting;
}
countDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
Adding, if you also want to get the unique elements, you can just use E6 set:
var set = new Set([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
You can count and print as you would want like this:
function getDuplicates(arr) {
var counts = {};
arr.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
console.log(counts);
}
function getDuplicates(arr) {
let lastNum = null;
let obj = {};
for ( let i = 0; i < arr.length; i++ ) {
if (arr[i] != lastNum){
lastNum = arr[i];
obj[arr[i]] = 1;
}else{
obj[arr[i]]++;
}
}
console.log(obj);
}
You can simply use Array#reduce() to count the occurrences and Array#filter() to remove the duplicates
getDuplicates([1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6]);
function getDuplicates(arr) {
var obj = arr.reduce((map, item) => (map[item] = ++map[item] || 1, map),{} );
var withoutDup = arr.filter((item, pos) => arr.indexOf(item) == pos);
console.log(JSON.stringify(obj));
console.log(JSON.stringify(withoutDup));
}
Here's one method how to solve it.
Firstly I've removed all duplicated elements from the given array, using new Set() and then iterated over it using Array#forEach and checked with Array#filter how many times given element appears in the passed array.
function getDuplicates(arr){
var filtered = [...new Set(arr)],
result = {};
filtered.forEach(function(v){
result[v] = arr.filter(c => c == v).length;
})
console.log(result);
}
getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
Array#reduce solution.
function getDuplicates(arr) {
var res = arr.reduce(function(s, a) {
s[a] = arr.filter(c => c == a).length;
return s;
}, {});
console.log(res);
}
getDuplicates([1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6]);
It looks as if you want to COUNT duplicates, but if all you want to do is remove duplicates (As headline states), as per #ChantryCargill s suggestion:
function removeDuplicates (arr) {
var results = [];
for(var i = 0; i < arr.length; i++) {
var item = arr[i];
if(results.indexOf(item) === -1) {
results.push(item);
}
}
return results;
}
console.log(removeDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]));
//[1, 2, 3, 4, 5, 6]
If you want to COUNT duplicates:
function getDuplicates(arr) {
var results = {};
for(var item of arr) {
if(!results[item]) {
results[item] = 0;
}
results[item]++;
}
return results;
}
console.log(getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]));
//{"1":4,"2":2,"3":4,"4":2,"5":3,"6":1}
Try this:
function getDuplicates(){
var numbers=Array.prototype.slice.call(arguments);
var duplicates={};
for(var index in numbers){
if(numbers.indexOf(numbers[index])==index)
continue;
duplicates[numbers[index]]= (duplicates[numbers[index]] || 0) + 1;
}
return duplicates;
}
console.log(getDuplicates(1,2,3,1,1,3,4,5,6,7,8,6));
/*
prints {
1: 2,
3: 1,
6: 1
}
*/
This question already has answers here:
How to remove repeated entries from an array while preserving non-consecutive duplicates?
(5 answers)
Closed 6 years ago.
I am trying to remove duplicates in an array in JavaScript. The given array being
array = [1,1,1,1,1,1,1,1,1,,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,1,1,1,1,1,2,2,2,2,2,2,2,2]
resultant_array = [1,2,3,1,2]
Here the second 1 is not considered as a duplicate
OR
array = [1,1,1,1,1,1,1,1,1,1,1,1]
resultant_array = [1]
any ideas how i can do this
You can use reduce like this:
var array = [1,1,1,1,1,1,1,1,1,,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,1,1,1,1,1,2,2,2,2,2,2,22];
var result = array.reduce(function(r, e) {
if(r[r.length - 1] != e) // if the last element in the result is not equal to this item, then push it (note: if r is empty then r[-1] will be undefined so the item will be pushed as any number is != undefined)
r.push(e);
return r;
}, []);
console.log(result);
var arr = [1,1,2,2,3,3];
var obj = {};
for(var i in arr) {
obj[arr[i]] = true;
}
var result = [];
for(var i in obj) {
result.push(i);
}
I set the keys of the object as the value of the array and there can't be multiple keys with the same value. Then I took all the keys and put it in the result.
You could check the predecessor with Array#reduce
var array = [1, 1, 1, 1, 1, 1, 1, 1, 1, , 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2],
result = array.reduce(function (r, a) {
return r[r.length - 1] === a ? r : r.concat(a);
}, []);
console.log(result);
Or use Array#filter and an object for the last value.
var array = [1, 1, 1, 1, 1, 1, 1, 1, 1, , 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2],
result = array.filter(function (a, i, aa) {
return this.last !== a && (this.last = a, true);
}, { last: undefined });
console.log(result);