I'm trying to create a function that groups an array of numbers based on a length parameter. The length represents the max length of each sub-array. The code works as it is meant to for getting the sub arrays, but what I'd like to do is make it sort by odd and even.
function myFunctionA(myArr1, myVal) {
newArr = [];
for ( x = 0; x < myArr1.length; x += myVal) {
newArr.push(myArr1.slice(x, x + myVal));
}
return newArr;
}
Console.log(myfunction([1,2,3,4,5,6,7,8,9,10],3))
This returns [[1,2,3],[4,5,6],[7,8,9],[10]]
What I'd like to do is go through each sub array at a time until the sub arrays are the correct length and add any leftover values to a sub array/s
This would look like
[[1,3,5][2,4,6][7,9][8,10]]
Since arr 0 and arr 1 are the correct length that we have stated in the console.log statement, 7 8 9 and 10 are left over. But since the can't create a full sub array and they are odds and even, they form two sub arrays with a side of 2.
Other examples:
myfunction([1,2,3,4,5,6,7],2)
Should return [[1,3],[2,4],[5,7],[6]]
myfunction([1,2,3,4,5,6,7,8],1)
Should return [[1][2][3][4][5][6][7][8]]
You could take an array for collecting all odd and even values and then push the group if it has zero items. By having the wanted size, create a new array.
function chunkenator(array, size, fn) {
let groups = [],
result = [];
for (let value of array) {
const group = fn(value);
if (!groups[group]) groups[group] = [];
if (!groups[group].length) result.push(groups[group]);
groups[group].push(value);
if (groups[group].length === size) groups[group] = [];
}
return result;
}
console.log(chunkenator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3, x => x % 2));
console.log(chunkenator([1, 3, 5, 7, 8, 9, 11, 13, 15], 3, x => x % 2));
One possibility would be to first seperate the numbers into even and odd numbers and then just loop over it, pushing the numbers into a new array switching between even and odd numbers.
It's not the cleanest piece of code, but it works.
function myfunction(arr, n) {
const evenOdd = arr.reduce((acc, e) => {
const ind = +(e % 2 === 0);
acc[ind] = acc[ind] || [];
acc[ind].push(e);
return acc;
}, []);
let ind = 0, res = [[]];
while (evenOdd[0].length || evenOdd[1].length) {
for (let i = n; i--;) {
const val = evenOdd[ind].shift();
if (val) res[res.length - 1].push(val)
}
ind = (ind + 1) % 2
res.push([])
}
res.pop()
return res;
}
for (const n of [1, 2, 3]) {
console.log(n,
myfunction([1, 2, 3, 4, 5, 6, 7, 8], n)
)
}
Related
I am trying to get 5 closest elements to given element, including that element, in array. For example, if we have:
const arr = [1, 2, 3, 4, 7, 11, 12, 13, 15, 17]
and I want to get 5 closest elements to 11, it should return [4, 7, 11, 12, 13]. If i pass 1 it should return [1, 2, 3, 4, 7]. If I pass 15 it should return [11, 12, 13, 15, 17].
I'm not sure what you meant;
You might've meant a code to find the element and return the five nearest elements to it by place in the array;
Or you might've meant a code to find the 5 numbers closest to a number you say.
IF you meant the first case
There are two ways to do so,
A value as a parameter
Use this code:
function closestNByValue(arr, value, n) {
let ind = arr.indexOf(value);
let finalArr = [];
if (n > arr.length) {
finalArr = Array.from(arr);
} else if (ind == -1) {
finalArr = [];
} else if (ind <= n/2 - 0.5) {
finalArr = arr.slice(0, n);
} else if (ind >= (arr.length - n/2) - 0.5) {
finalArr = arr.slice(-n);
} else if (n%2 == 0) {
finalArr = arr.slice(ind-(n/2), ind+(n/2));
} else {
finalArr = arr.slice(ind-(n/2 - 0.5), ind+(n/2 + 0.5));
}
return finalArr;
}
console.log(closestNByValue([1, 2, 3, 4, 7, 11, 12, 13, 15, 17], 11, 5))
How does it do the job?
Okay first we need to find the index of the value and save it in ind (short form of 'index') and we check multiple different situations for what the ind is so we'd be able to output the best answer as finalArr.
There are two exceptions; what if there was no such value in our array? then ind = -1 and we'd return an empty array; or what if the number of elements nearby that we seek is larger than or equal to the arr.length? then we'd return all of the arr.
But if there were no exceptions, there are three different situations for the ind; first, ind is a number that makes us have all of the finalArr values from the first of arr, second, ind be a number that makes us have all of the finalArr values from the last of arr, and third, ind being a number that we have to select half from the indexes smaller than ind and half, larger.
If it is the third way, the way we select we'd be different depending on the oddity of the numbers we want to select.
And we'll have a conditional statement for each situation and return the finalArr.
An index as a parameter
function closestNByIndex(arr, ind, n) {
let finalArr = [];
if (n > arr.length) {
finalArr = Array.from(arr);
} else if (ind == -1) {
finalArr = [];
} else if (ind <= n/2 - 0.5) {
finalArr = arr.slice(0, n);
} else if (ind >= (arr.length - n/2) - 0.5) {
finalArr = arr.slice(-n);
} else if (n%2 == 0) {
finalArr = arr.slice(ind-(n/2), ind+(n/2));
} else {
finalArr = arr.slice(ind-(n/2 - 0.5), ind+(n/2 + 0.5));
}
return finalArr;
}
console.log(closestNByIndex([1, 2, 3, 4, 7, 11, 12, 13, 15, 17], 5, 5))
Similar to the first code it works, though we have the index and we don't search for it.
The point is, if you use the function with value, it'd do the nearest 5 elements of the first value that equals the entry but such confusion is not being tolerated in the second code.
IF you meant the second case
This is a code I coded:
const arr = [1, 2, 3, 4, 7, 11, 12, 13, 15, 17];
function allDiff(arr, num1, num2) {
const finalArr = [];
const x = Math.abs(num2 - num1);
for (let y = 0; y < arr.length; y++) {
if (Math.abs(arr[y] - num1) == x) {
finalArr.push(arr[y]);
}
}
return finalArr;
}
function deleteArr(arr, delet) {
for (let x = 0; x < arr.length; x++) {
if (delet.includes(arr[x])) {
delete arr[x];
}
}
return arr;
}
function closest(arr, num) {
const map = new Map()
arr2 = Array.from(arr);
let key, value;
for (let x = 0; x < arr2.length; x++) {
key = Math.abs(arr2[x] - num);
value = allDiff(arr2, num, arr2[x]);
arr2 = deleteArr(arr2, value);
map.set(key, value);
}
return map;
}
function closestN(arr, num, n) {
const map = closest(arr, num);
const mapKeys = Array.from(map.keys());
const mapKeysSorted = mapKeys.sort(function(a, b) {
return a - b
});
let finalArr = [];
let y;
for (let i = 0; i < mapKeysSorted.length; i++) {
if (n <= 0) {
break;
}
y = map.get(mapKeysSorted[i]);
if (n < y.length) {
finalArr = finalArr.concat(y.slice(0, n + 1));
break;
}
finalArr = finalArr.concat(y);
n -= y.length;
}
return finalArr;
}
console.log(closestN(arr, 11, 5));
It might be a little too long, but I have programmed it as you can give it any array (arr) with integer values, an integer (num) that you'd like it to be the base and another integer (n) for the number of the size of the output array, 5 in this case.
Explaining the code
The function closest would return a map of (the difference between the numbers, a list of the numbers in the arr that differs the number equal to their key).
The main function, closestN, calls the closest function and saves the map in the map variable.
Then it sorts the keys of the map in mapKeysSorted.
Now, a for loop loops through the mapKeySorted array and pushes new elements to the finalArr until the size of the finalArr reaches the number of elements we seek.
The main function is the closestN.
Here's a way to get to your goal:
To start, first thing to do is finding the index of the wanted number in the array. Example index of 1 in your array arr is 0. The index will help in extracting the numbers later on. The method findIndex will help us in finding the index.
Then, we need to find the position at which will start extaracting the closest numbers (in terms of position not value). As seen from the desired output you have provided, usually you want the returned array to be in the following structure:
output: [
2 nearest numbers (from N left),
the wanted number,
2 nearest numbers (from N right)
]
This can get tricky so we should make sure to deal with some edge case like when the wanted element is sitting at position 0.
Extract the numbers and return them as an array as described by your desired output. The use of slice method will come in handy here which allow us to extract the numbers just as we need.
Here's a live demo demonstrating solution:
const arr = [1, 2, 3, 4, 7, 11, 12, 13, 15, 17],
/** a function that returns an array containing the "5" (depending on "arr" length that could be less) nearest numbers (in terms of position) in "arr" array to the supplied number "n" */
findClosestNumbers = n => {
/** make sure we don't exceed the array length */
const toTake = 5 > arr.length ? arr.length : 5,
/** find the index of the wanted nulber "n", if "-1" is returned then "n" cannot be found ion the array "arr" */
idx = arr.findIndex(el => n == el),
/**
* from where we should start returning the nearest numbers (the position of the first number to extract from "arr"
* the below condition help deal with some edge cases like when "n" is the last element in "arr"
*/
startIdx = idx + toTake / 2 > arr.length ?
arr.length - 5 :
(idx - 2 >= 0 ?
idx - 2 :
0);
/** return the nearest numbers or return an empty array "[]" if the number "n" is not found on the array "arr" */
return idx == -1 ? [] : arr.slice(startIdx, startIdx + 5);
};
/** run for various scenarios */
console.log('For 1 =>', findClosestNumbers(1));
console.log('For 11 =>', findClosestNumbers(11));
console.log('For 15 =>', findClosestNumbers(15));
console.log('For 17 =>', findClosestNumbers(17));
.as-console-wrapper {
max-height: 100%!important;
}
The demo above is meant to help you understand how things could work and it is not the only way to get to your goal. Also, because I kept it as simple as possible, the above demo is wide open for improvements.
Have the function ArrayChallenge(arr) take the array of integers stored in arr, and determine if any two numbers (excluding the first element) in the array can sum up to the first element in the array. For example: if arr is [7, 3, 5, 2, -4, 8, 11], then there are actually two pairs that sum to the number 7: [5, 2] and [-4, 11]. Your program should return all pairs, with the numbers separated by a comma, in the order the first number appears in the array. Pairs should be separated by a space. So for the example above, your program would return: 5,2 -4,11
If there are no two numbers that sum to the first element in the array, return -1
Input: [17, 4, 5, 6, 10, 11, 4, -3, -5, 3, 15, 2, 7]
Output: 6,11 10,7 15,2
Final Output: --6--,--1----1-- --1--0,7 --1----5--,2
Input: [7, 6, 4, 1, 7, -2, 3, 12]
Output: 6,1 4,3
Final Output: --6--,--1-- 4,3
My approach
function ArrayChallenge(arr) {
var sum = []
for (var i = 0; i < arr.length; i++){
for (var j = i + 1; j < arr.length; j++){
if(arr.[i] + arr[j]=== )
}
}
// code goes here
return arr;
}
// keep this function call here
console.log(ArrayChallenge(readline()));
Can you please help me with this ?
Logic
Loop through the array.
Start from index 1 to last node (except index 0) in the outer loop.
Srart from one node next to the outer loop in the inner loop.
Check the sum of both nodes.
If the sum value is same as the node at first index, push that to sum array in required format.
Check the length of sum array. If length > 0 the join sum array and return. Else return -1
Working Code
const input = [17, 4, 5, 6, 10, 11, 4, -3, -5, 3, 15, 2, 7];
const input2 = [7, 6, 4, 1, 7, -2, 3, 12];
const input3 = [37, 6, 4, 1, 7, -2, 3, 12];
function ArrayChallenge(arr) {
var sum = []
for (var i = 1; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] + arr[j] === arr[0]) {
sum.push([arr[i], arr[j]].join());
}
}
}
return sum.length > 0 ? sum.join(" ") : -1;
}
console.log(ArrayChallenge(input));
console.log(ArrayChallenge(input2));
console.log(ArrayChallenge(input3));
Your approach uses a O(n^2) level complexity. This can be solved using O(n) if you're willing so sacrifice a little on space complexity.
What you can do is :
Make an empty object.
store all values of the array (not the 0th element) in the object as key and add it's value as true.
Loop the array (from 1st index). Take the value and subtract it from the 0th element. find this subtracted value from the object, If it does not return undefined, make a pair and save it.
One drawback of this method is, you'll find duplicate entries in the result.
This Approach uses O(n) Time complexity and O(n) space complexity
function ArrayChallange(arr) {
let numObj = {}
let i = 1
let result = []
let tempVal
// Pushing all elements of arr (from index 1) inside numObj
while(i<arr.length){
numObj[arr[i]] = true
}
i = 1
// Looping the array to find pairs
while(i < arr.length){
tempVal = numObj[Math.abs(arr[0] - arr[i])]
if(tempVal){
result.push(arr[i].toString() +","+tempVal.toString())
}
}
if(result.length !== 0)
return result.join(" ")
else
return -1
}
You could use a reducer followed by a forEach loop in order to push the pairs to an empty array, then join them at the end.
const ArrayChallenge = (nums) => {
const pairs = []
// Get the first and remove it from the array
const first = nums.splice(0, 1)[0]
nums.reduce((all, curr) => {
all.forEach((a) => {
// Check if we have a match
if (curr + a === first) {
// check if it's already in the array
// we don't want duplicates
if (pairs.indexOf(`${a},${curr}`) === -1 && pairs.indexOf(`${curr},${a}`) === -1) {
// push the pair to the array separated by a space
pairs.push(`${curr},${a}`)
}
}
})
return all
}, nums) // we pass in nums as the starting point
// If there are no pairs then return -1
if (pairs.length === 0) {
return -1
} else {
// Join the pairs together with a space
const result = pairs.join(' ')
// Replace each digit (\d) with hyphens before and after
const parsed = result.replace(/(\d)/g, '--$1--')
return parsed
}
}
const result1 = ArrayChallenge([17, 4, 5, 6, 10, 11, 4, -3, -5, 3, 15, 2, 7])
console.log(result1)
const result2 = ArrayChallenge([7, 6, 4, 1, 7, -2, 3, 12])
console.log(result2)
I have 2 questions, how can I get value instead of value inside array and how can I make this code shorter and declarative.
arr = [16, 4, 11, 20, 2]
arrP = [7, 4, 11, 3, 41]
arrTest = [2, 4, 0, 100, 4, 7, 2602, 36]
function findOutlier(arr) {
const isPair = (num) => num % 2 === 0
countEven = 0
countOdd = 0
arr1 = []
arr2 = []
const result = arr.filter((ele, i) => {
if (isPair(ele)) {
countEven++
arr1.push(ele)
} else {
countOdd++
arr2.push(ele)
}
})
return countEven > countOdd ? arr2 : arr1
}
console.log(findOutlier(arrTest))
Filtering twice may be more readable.
even = arr.filter((x) => x % 2 == 0);
odd = arr.filter((x) => x % 2 == 1);
if (even.length > odd.length) {
return even;
} else {
return odd;
}
If you're looking to do this with one loop, consider using the array reduce method to put each number into an even or odd bucket, and then compare the length of those buckets in your return:
function findOutlier(arr) {
const sorted = arr.reduce((acc, el) => {
acc[el % 2].push(el);
return acc;
},{ 0: [], 1: [] })
return sorted[0].length > sorted[1].length ? sorted[1] : sorted[0];
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(findOutlier(arr));
Note that this does not handle when the arrays are the same length gracefully (right now it'll just return the odd array).
You could take an object with the wanted part for collecting and add a short circuit if one of the types has a count of one and the others have a count greater than one.
const
isPair = num => num % 2 === 0,
findOutlier = array => {
count = { true: [], false: [] };
for (const value of array) {
count[isPair(value)].push(value);
if (count.true.length === 1 && count.false.length > 1) return count.true[0];
if (count.false.length === 1 && count.true.length > 1) return count.false[0];
}
};
console.log(...[[16, 4, 11, 20, 2], [7, 4, 11, 3, 41], [2, 4, 0, 100, 4, 7, 2602, 36]].map(findOutlier));
Here is an solution that selects the even or odd array based on the modulo result.
function findOutlier(integers) {
const even = [], odd = [], modulos = [even, odd];
for (const integer of integers) {
modulos[Math.abs(integer % 2)].push(integer);
}
return even.length > odd.length ? odd : even;
}
console.log(findOutlier([2, 4, 0, 100, 4, 7, 2602, 36]));
You unfortunately do need Math.abs() to handle negative values, because -3 % 2 == -1.
See: JavaScript % (modulo) gives a negative result for negative numbers
However the name findOutlier lets me assume there is only a single outlier within the provided list. If this is the case you can optimize the algorithm.
function findOutlier(integers) {
// With less than 3 integers there can be no outlier.
if (integers.length < 3) return;
const isEven = (integer) => integer % 2 == 0;
const isOdd = (integer) => !isEven(integer);
// Determine the outlire based on the first 3 elements.
// If there are 0 or 1 integers even, the outlire is even.
// if there are 2 or 3 integers even, the outlier is odd.
const outlier = integers.slice(0, 3).filter(isEven).length < 2
? isEven
: isOdd;
return integers.find(outlier);
}
console.log(findOutlier([2, 4, 0, 100, 4, 7, 2602, 36]));
You can do this without creating intermediate arrays by simply comparing each element to its neighbors and returning that element if it is different to both, or undefined if no outliers are found. This returns in the same iteration in which the outlier is first encountered, and returns the value itself and not an array.
function findOutlier(array) {
const
len = array.length,
isEven = (n) => n % 2 === 0;
for (const [i, value] of array.entries()) {
let
prev = array[(i-1+len)%len], // loop around if < 0 (first element)
next = array[(i+1)%len]; // loop around if >= length (last element)
if (isEven(value) !== isEven(prev) && isEven(value) !== isEven(next)) {
return value;
}
}
return undefined;
}
const arrays = [[16, 4, 11, 20, 2], [7, 4, 11, 3, 41], [2, 4, 0, 100, 4, 7, 2602, 36]]
console.log(...arrays.map(findOutlier));
Now that OP clarified the requirements (at least in a comment) this allows a different approach:
function findOutlier(array) {
let odd = undefined, even = undefined;
for (let i of array) {
let isEven = i % 2 == 0;
if (odd !== undefined && even !== undefined)
return isEven ? odd : even;
if (isEven) even = i;
else odd = i;
}
if (odd !== undefined && even !== undefined)
return array[array.length-1];
}
console.log(findOutlier([2,4,6,8,10,5]))
The algorithm will iterate the array, and store the lastest found odd and even numbers, respectively.
If we discovered both an odd and an even number already, with the current number we can decide, which of them is the outlier: If the current number is even, it's at least the second even number we found. Thus, the found odd number must be the outlier. The same applies vice versa if the current number is odd. The special case, if the outlier is the last element of the array, is checked with an additional condition after the loop.
If all numbers are odd or even (ie there is no outlier) this function will return undefined. This algorithm does not throw an error, if the preconditions are not met, ie if there is more than one outlier.
My goal here is to find the prime numbers:
let arr = [2, 3, 4, 6, 9, 10, 11, 15];
let ret = [];
arr.filter((z, ind) => {
if (ind > 0) {
ret.every(x => {
!Number.isInteger(z / x) ? ret.push(z) : false;
});
} else {
ret.push(z);
}
});
console.log(ret); // should be: [2,3,11]
It works for even numbers, but it doesn't work for the odd.
Fixed your code:
let arr = [2,3,4,6,9,10,11,15]
let ret = [];
arr.filter((z, ind) => {
if(ind > 0){
if(ret.every( x => !Number.isInteger(z/x)) ){
ret.push(z)
}
} else { ret.push(z) }
})
console.log(ret)
The Array.filter() method returns an array, so no need to generate the array by pushing the elements to an external array.
The prime check is easier with a for loop. Check that the number doesn't produce an integer if divided by all the numbers between 2 and half its size (rounded down). We need to check all half way, because every number that is greater than half the number we are checking, would produce a result that is less than 2, and 2 is the smallest integer divisor of a number.
const arr = [2, 3, 4, 6, 9, 10, 11, 15];
const isPrime = num => {
if(num < 4) return true; // 1, 2, 3 are prime numbers
const div = Math.floor(num / 2); // the max number to use as divider
for(let i = 2; i <= div; i++) {
if(Number.isInteger(num / i)) return false; // if the result is an integer, it's not a prime number
}
return true; // it's a prime number
};
const result = arr.filter(isPrime);
console.log(result); // should be: [2,3,11]
Hello I am taking an array of integers with ranging numbers from 1 - 100 and I'm counting the duplicated numbers within it. Example, array[1,1,1,1,1,100,3,5,2,5,2,23,23,23,23,23,]. Result = 1 - 5 times, 5 - 2 times, 2 - 2 times, 23 - 5 times. I cannot see how to make this work I have tried to edit this code snippet so that it counts and returns the number of duplicates of a specific integer that is a duplicate but I could not see how to do it. Please assist Thank You.
https://repl.it/#youngmaid/JS-ALGORITHMS-Counting-Duplicates
//To count or reveal duplicates within an array. Using the array method of sort() is one way.
//Sort the following array using .sort(), which put the items in the array in numerical or alphabetical order.
//Create a new variable for the sorted array.
//Also create a new variable for an empty array.
//Create a loop using the length of the first, original array with an increment of "++".
//Create an if statement that includes adding an item comparing to the index.
//Then push the emply array in the sorted array.
//console log the new array.
let duplicateArr = [5, 3, 7, 4, 7, 5, 3, 2, 7, 3, 2];
let sortArr = duplicateArr.sort();
let newArr = [];
for(let i = 0; i < duplicateArr.length; i++) {
if(sortArr[i + 1] == sortArr[i]){
newArr.push(sortArr[i]);
}
}
console.log(newArr);
//The other way or more detailed/reusable approach is to create a function and variable hash table.
//The hash table to place all the items in the array.
//Then create another variable placing duplicates in the array.
//Then go through each item in the array through a for loop. (Using arr as the argument).
//Create a conditional if/else statement. If the item in the hash table does not exist, then insert it as a duplicate.
function duplicates(arr) {
let hashTable = [];
let dups = [];
for (var i = 0; i < arr.length; i++){
if (hashTable[arr[i].toString()] === undefined) {
hashTable[arr[i].toString()] = true;
} else {
dups.push(arr[i]);
}
}
return dups;
}
duplicates([3, 24, -3, 103, 28, 3, 1, 28, 24]);
If I understand correctly, you could achieve this via Array#reduce() as shown below:
let duplicateArr = [5, 3, 7, 4, 7, 5, 3, 2, 7, 3, 2];
/* Reduce the input duplicateArr to a map relating values to counts */
const valueCounts = duplicateArr.reduce((counts, value) => {
/* Determine the count of current value from the counts dictionary */
const valueCount = (counts[ value ] === undefined ? 0 : counts[ value ])
/* Increment count for this value in the counts dictionary */
return { ...counts, ...{ [value] : valueCount + 1 } }
}, {})
/* Remove values with count of 1 (or less) */
for(const value in valueCounts) {
if(valueCounts[value] < 2) {
delete valueCounts[value]
}
}
/* Display the values and counts */
for(const value in valueCounts) {
console.log(`${ value } occours ${ valueCounts[value] } time(s)` )
}
Reasonably basic loop approach
const data = [1, 1, 1, 1, 1, 100, 3, 5, 2, 5, 2, 23, 23, 23, 23, 23, ]
function dupCounts(arr) {
var counts = {};
arr.forEach(function(n) {
// if property counts[n] doesn't exist, create it
counts[n] = counts[n] || 0;
// now increment it
counts[n]++;
});
// iterate counts object and remove any that aren't dups
for (var key in counts) {
if (counts[key] < 2) {
delete counts[key];
}
}
return counts
}
console.log(dupCounts(data))
Here using only 1 loop.
let duplicateArr = [5, 3, 7, 4, 7, 5, 3, 2, 7, 3, 2]
let sortArr = duplicateArr.sort()
let current = 0, counter = 0
sortArr.forEach(n => {
if (current === n) {
counter++
}
else {
if (counter > 1){
console.log(current + " occurs " + counter + " times.")
}
counter = 1
current = n
}
})
if (counter > 1){
console.log(current + " occurs " + counter + " times.")
}
The cleanest way is using ES6 Map
function duplicates(arr) {
// This will be the resulting map
const resultMap = new Map();
// This will store the unique array values (to detect duplicates using indexOf)
const occurrences = [];
for (let i of arr){
if (occurrences.indexOf(i) !== -1) {
// Element has a duplicate in the array, add it to resultMap
if (resultMap.has(i)) {
// Element is already in the resultMap, increase the occurrence by 1
resultMap.set(i, resultMap.get(i) + 1);
} else {
// Element is not in resultMap, set its key to 2 (the first 2 occurrences)
resultMap.set(i, 2);
}
} else {
// Element is showing for the first time (not a duplicate yet)
occurrences.push(i);
}
}
return resultMap;
}
// To iterate on the map keys and values use this
for (const [key, value] of map) {
console.log(key + ' - ' + value + ' times');
}
You can just iterate over all of the unique values and then count how many of them exists.
here is a sample code:
let duplicateArr = [5, 3, 7, 4, 7, 5, 3, 2, 7, 3, 2];
let sortArr = duplicateArr.sort();
let newArr = {};
let duplicateValues = [];
for (let i = 0; i < duplicateArr.length; i++) {
let count = 0;
let k = 0;
while (i + k < duplicateArr.length && sortArr[i] == sortArr[i + k]) {
count++;
k++;
}
if (count > 1) {
newArr[sortArr[i]] = count;
duplicateValues.push(sortArr[i]);
}
i = i + k;
}
console.log("duplicate items with count:", newArr);
console.log("duplicate items:", duplicateValues);
Using Array.prototype.reduce() you can create a hash object variable containing as keys the numbers in the duplicateArr array variable and the values are the number of repeated times..
Code:
const duplicateArr1 = [5, 3, 7, 4, 7, 5, 3, 2, 7, 3, 2];
const duplicateArr2 = [1, 1, 1, 1, 1, 100, 3, 5, 2, 5, 2, 23, 23, 23, 23, 23];
const getStringOfDuplicated = array => {
const hash = array.reduce((a, c) => (a[c] = ++a[c] || 1, a), {});
return Object.entries(hash)
.filter(([k, v]) => v > 1)
.sort(([ak, av], [bk, bv]) => bv - av)
.map(([k, v]) => `${k} - ${v} times`)
.join(', ');
};
console.log(getStringOfDuplicated(duplicateArr1));
console.log(getStringOfDuplicated(duplicateArr2));