Finding the mode's of an array? Javascript - javascript

Okay, I've only figured out how to get one mode out of the array..
But I want to get 2, 3 or more if they occur the same amount of times.
This is the code:
var frequency = {}; // array of frequency.
var maxFreq = 0; // holds the max frequency.
for (var i in array) {
frequency[array[i]] = (frequency[array[i]] || 0) + 1; // increment frequency.
if (frequency[array[i]] > maxFreq) { // is this frequency > max so far ?
maxFreq = frequency[array[i]]; // update max.
mode = array[i]; // update result.
}
}
So right now, if I've got a array = [3, 8, 3, 6, 1, 2, 9];
I get mode = 3;
But what I'm looking for is if array = [3, 6, 1, 9, 2, 3, 6, 6, 3, 1, -8, 7];
I want to get the mode = 3, 6;

The question doesn't state how to get the modes, but if we want them in an array, we could change the code like this:
function getModes(array) {
var frequency = []; // array of frequency.
var maxFreq = 0; // holds the max frequency.
var modes = [];
for (var i in array) {
frequency[array[i]] = (frequency[array[i]] || 0) + 1; // increment frequency.
if (frequency[array[i]] > maxFreq) { // is this frequency > max so far ?
maxFreq = frequency[array[i]]; // update max.
}
}
for (var k in frequency) {
if (frequency[k] == maxFreq) {
modes.push(k);
}
}
return modes;
}
alert(getModes([3, 6, 1, 9, 2, 3, 6, 6, 3, 1, -8, 7]));

function modeCount(data) {
let modecount = [];
let valueArr = [];
let dataSet = new Set(data);
for (const iterator of dataSet) {
const filteredNum = data.filter((num) => iterator === num);
modecount.push({
mode: iterator,
count: filteredNum.length
});
}
modecount.sort((a, b) => {
return b.count - a.count;
});
modecount.forEach(value => {
if (value.count === modecount[0].count) {
valueArr.push(value.mode);
}
});
return valueArr;
}
let ages = [3, 6, 1, 9, 2, 3, 6, 6, 3, 1, -8, 7]
console.log(modeCount(ages));

Related

How do I write a function that return the the first number with highest frequency(mode)

I am solving a problem which asks me to return the number with the highest frequency(mode). For example, if arr contains [3, 9, 3, 1, 6] the output should be 3. If there is more than one mode, I want to return the one that appeared first. [6, 6, 3, 3, 5, 5] should return 6 because it appeared first. If there is no mode, I want to return 0. The array will not be empty. I am new to algorithms, please suggest a simpler solution for me.
function Mode(arr) {
const arrayObject = {};
arr.forEach(arr => {
if(!arrayObject[arr]) {
arrayObject[arr] = 1
// console.log(arrayObject)
} else if(arrayObject[arr]){
arrayObject[arr] += 1
// console.log(arrayObject)
}
})
console.log(arrayObject) // { '3': 2, '5': 2, '6': 2 } array keys are automatically sorted in ascending other.This could be the problem but I don't know how to unsort the arrays//
let highestValueKey = 0;
let highestValue = 0
for(let key in arrayObject) {
const value = arrayObject[key]
if(value > highestValue) {
highestValue = value
highestValueKey = key
}
}
return Number(highestValueKey)
}
console.log(Mode([6, 6, 3, 3, 5, 5])) // 3 instead of 6
Just keep track of both count AND when it was first seen.
function mode (arr) {
const countSeen = {};
const firstSeen = {};
for (let i = 0; i < arr.length; i++) {
let elem = arr[i];
if (! countSeen[elem]) {
countSeen[elem] = 1;
firstSeen[elem] = i;
}
else {
countSeen[elem]++;
}
}
let mostSeenCount = 0;
let mostSeenValue = null;
for (let elem of Object.keys(countSeen)) {
if (mostSeenCount < countSeen[elem] ||
(mostSeenCount == countSeen[elem] && firstSeen[elem] < firstSeen[mostSeenValue])
) {
mostSeenCount = countSeen[elem];
mostSeenValue = elem;
}
}
return mostSeenValue;
}
console.log(mode([5, 6, 6, 6, 3, 3, 5, 5]))
You could use a Map whose keys are the array values, and the corresponding Map value is the frequency count:
Create the map and initialise the counts with 0
Increment the count as each input value is visited.
Use Math.max to get the greatest count from that map
Iterate the map to find the first count that matches that maximum
As Map entries are iterated in insertion order, the correct key will be identified in the last step.
function mode(arr) {
const counts = new Map(arr.map(i => [i, 0]));
for (const i of arr) counts.set(i, counts.get(i) + 1);
const maxCount = Math.max(...counts.values());
for (const [i, count] of counts) {
if (count == maxCount) return i;
}
}
console.log(mode([3, 9, 3, 1, 6])); // 3
console.log(mode([6, 6, 3, 3, 5, 5])); // 6
console.log(mode([3, 9, 3, 6, 1, 9, 9])); // 9
console.log(mode([5, 6, 6, 6, 3, 3, 5, 5])); // 5
You could use reduce to count the number of occurrences, then choose the max from there.
function mode(arr) {
const counts = arr.reduce((result, value, index) => {
// result is the object we're building up.
// value is the current item from the array.
// index is value's position within the array
// if result[value] doesn't already exist, create it
result[value] = (result[value] || { index, value, count: 0 });
// increment the 'count' for this value
result[value].count++;
// return the updated result
return result;
}, {});
// sort the entries by count in descending order, then by index
// ascending such that sorted[0] will be the entry with the highest
// count, and lowest index if more that one element has the same count
const sorted = Object.values(counts)
.sort((
{count: ca, index: ia},
{count: cz, index: iz}
) => (cz - ca) || (ia - iz));
// then return that entry's value
return sorted[0].value;
}
console.log(mode([6, 6, 3, 3, 5, 5])) // 6
console.log(mode([3, 9, 3, 1, 6])) // 3
console.log(mode([3, 9, 3, 6, 1, 9, 9])) // 9

Find the smallest missing positive int in array in js

How do I find the smallest missing positive integer from an array of integers in js? I didn't find an answer to my question, all I found was in other languages.
Here's an example array:
[-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2]
The result should be 8.
You could take an object of seen values and a min variable for keeping track of the next minimum value.
const
data = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2],
ref = {};
let min = 1;
for (const value of data) {
if (value < min) continue;
ref[value] = true;
while (ref[min]) min++;
}
console.log(min);
You could create an array of positive integer (in this example integers has values from 0 to 10), then use Math.min on integers array filtered with initial array (that was filtered taking only positive numbers):
let integers = Array.from(Array(11).keys());
let arr = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2];
console.log(Math.min(...integers.filter(x => x > 0 && !arr.filter(x => x > 0).includes(x))));
You can do like below to avoid multiple loops.
Simplest solution is when numbers from 1-10, sum of all number will 55 using this formula (n * (n + 1)) / 2;.
the missing number will be 55-(sum of remaining numbers).
const list = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2];
const missing = (list) => {
let sum = 0;
let max = 0;
let ref = {};
for (let i = 0; i < list.length; i++) {
const ele = list[i];
if (ele > 0 && !ref[ele]) {
ref[ele] = true;
max = max < ele ? ele : max;
sum += ele;
}
}
const total = (max * (max + 1)) / 2;
return total - sum; // will work if only one missing number
// if multiple missing numbers and find smallest one
// let result = 0;
// for (let i = 1; i <= total - sum; i++) {
// if (!ref[i]) {
// result = i;
// break;
// }
// }
// return result;
};
console.log(missing(list));
I create function for finding the smallest positive.
arr = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2]
function getSmallestPos(arr) {
pi = [...new Set(
arr.filter(n => n > 0)
.sort((a, b) => a - b ))
];
for (i = 0; i < pi.length; i++) {
if ( pi[i] != (i+1)) {
return (i+1);
}
}
}
console.log(getSmallestPos(arr));
Your questions title contradicts the body of your answer.
To get the smallest positive integer you might try this:
const array = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2];
// filter array to get just positive values and return the minimum value
const min = Math.min(...array.filter(a => Math.sign(a) !== -1));
console.log(min);
For getting the missing value check this out:
const array = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2];
const getMissingPositiveInt = (array) => {
// filter array to get just positive values and sort from min to max (0, 1, 4, 5 ...)
const min = array.filter(a => Math.sign(a) !== -1).sort((a,b) => a-b);
for (let i=min[0]; i<array.length; i++) // loop from min over whole array
if (!min.includes(i)) // if array doesnt include index ...
return i; // ... you got your missing value and can return it
}
console.log(getMissingPositiveInt(array));

Count repeated numbers in array and return true (Cognitive Complexity)

I need to check if a number repeats itself at least three times in an array. How can I refactor it to decrease the Cognitive Complexity that Lint keeps complaining about.
Heres my code:
let array11 = [1, 3, 2, 3, 5, 6, 7, 8, 9, 0, 1];
function checkDuplicateNumber (array11) {
for (let i = 0; i < array11.length; i += 1) {
let sameNumberLoop = 0;
for (let i2 = i; i2 < array11.length; i2 += 1) {
if (array11[i] === array11[i2]) {
sameNumberLoop += 1;
if (sameNumberLoop >= 3) {
return true;
}
}
}
}
}
Instead of iterating multiple times, iterate just once, while counting up the number of occurrences in an object or Map:
let array11 = [1, 3, 2, 3, 5, 6, 7, 8, 9, 0, 1];
function checkDuplicateNumber (array) {
const counts = {};
for (const num of array) {
counts[num] = (counts[num] || 0) + 1;
if (counts[num] === 3) return true;
}
return false;
};
console.log(checkDuplicateNumber(array11));
console.log(checkDuplicateNumber([3, 1, 3, 5, 3]));
let array11 = [1, 3, 2, 3, 5, 6, 7, 8, 9, 0, 1]
let array22 = [1, 3, 2, 3, 5, 6, 7, 1, 9, 0, 1]
function checkDuplicateNumber(arr) {
const map = new Map()
return arr.some((v) => (map.has(v) ? (++map.get(v).count === 3) : (map.set(v, { count: 1 }), false)))
}
console.log(checkDuplicateNumber(array11))
console.log(checkDuplicateNumber(array22))

Find Max Slice Of Array | Javascript

I need to find the maximum slice of the array which contains no more than two different numbers.
Here is my array [1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]
My thought process on this is to find the numbers that are not repeated and return their index within a new array.
Here is what I have so far:
function goThroughInteger(number) {
var array = [];
//iterate the array and check if number is not repeated
number.filter(function (element, index, number) {
if(element != number[index-1] && element != number[index+1]) {
array.push(index);
return element;
}
})
console.log(array);
}
goThroughInteger([1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]);
I'm unsure where to go next, I'm struggling to understand the question that being - find the maximum slice which contains no more than two different numbers - that confuses me.
A solution with a single loop, which checks the last values and increments a counter.
function getLongestSlice(array) {
var count = 0,
max = 0,
temp = [];
array.forEach(function (a) {
var last = temp[temp.length - 1];
if (temp.length < 2 || temp[0].value === a || temp[1].value === a) {
++count;
} else {
count = last.count + 1;
}
if (last && last.value === a) {
last.count++;
} else {
temp.push({ value: a, count: 1 });
temp = temp.slice(-2);
}
if (count > max) {
max = count;
}
});
return max;
}
console.log(getLongestSlice([58, 800, 0, 0, 0, 356, 8988, 1, 1])); // 4
console.log(getLongestSlice([58, 800, 0, 0, 0, 356, 356, 8988, 1, 1])); // 5
console.log(getLongestSlice([1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8])); // 10
function goThroughInteger(array) {
var solutionArray = [];
var max = 0;
for (var i = 0; i <= array.length; i++) {
for (var j = i + 1; j <= array.length; j++) {
var currentSlice= array.slice(i,j);
var uniqSet = [...new Set(currentSlice)];
if(uniqSet.length <3) {
if(currentSlice.length>max) {
max= currentSlice.length;
}
}
}
}
console.log(max);
}
goThroughInteger([1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]);
This solution checks every possible slice of the array, checks if it has not more than 2 different numbers and finally prints out the length of the longest slice.
This is a possible solution, with complexity O(n²) (as pointed out by #le_m in the comments)
goThroughInteger = (list) => {
let scores = list.reduce((slices, num, pos) => {
let valid = [num];
let count = 0;
for (let i = pos; i < list.length; i++) {
if (valid.indexOf(list[i]) == -1) {
if (valid.length < 2) {
valid.push(list[i]);
count++;
} else {
break;
}
} else {
count++;
}
}
slices[pos] = { pos, count };
return slices;
}, []);
scores.sort((a, b) => b.count - a.count);
let max = scores[0];
return list.slice(max.pos, max.pos + max.count);
};
console.log(goThroughInteger([1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]));
console.log(goThroughInteger([58, 800, 0, 0, 0, 356, 8988, 1, 1]));
```
The solution calculates the 'score' at every position of the input list, counting the length of a sequence of no more than 2 different values, then takes the result with the highest score and extracts a slice from the original list based on that information.
It can definitely be cleaned and optimized but I think it's a good starting point.
Using the sliding window algorithm in O(n) time:
const arr = [1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8, 1, 1 ,1 ,1, 8, 1, 1, 8, 8];
const map = {
length: 0
};
let required = [];
for(start = 0, end = 0; end <= arr.length; ){
if(map.length > 2){
if(map[arr[start]] === 1){
delete map[arr[start]];
map.length --;
}else{
map[arr[start]]--;
};
start++;
}else{
if(end - start > required.length){
required = arr.slice(start, end);
};
if(map[arr[end]]){
map[arr[end]]++;
}else{
map[arr[end]] = 1;
map.length++;
}
end++;
}
}
console.log(required);

Counting the same nearest values in Javascript array

Given this array:
[1, 1, 2, 1, 1, 1, 2, 3, 4, 4, 4, 6, 4, 4]
How can I efficently count the nearest same elements in array, the result I would expect is:
1 => 2,
2 => 1,
1 => 3,
2 => 1,
3 => 1,
4 => 3,
6 => 1,
4 => 2
I don't know how to formulate correctly the question but I think the example is pretty clear.
I tried using reduce to make more compact and elegant but I always get a value with total number of same value in array.
let result = testArray.reduce((allValues, value) => {
if(value in allValues){
allValues[value]++;
} else {
allValues[value] = 1;
}
return allValues;
}, {});
You could check the last element and if equal, increment count, if not push a new object to the result set.
var array = [1, 1, 2, 1, 1, 1, 2, 3, 4, 4, 4, 6, 4, 4],
count = array.reduce((r, a, i, aa) => {
if (aa[i - 1] === a) {
r[r.length - 1].count++;
} else {
r.push({ value: a, count: 1 });
}
return r;
}, []);
console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Another solution using Array.prototype.reduce and a hash table - see demo below:
var array = [1, 1, 2, 1, 1, 1, 2, 3, 4, 4, 4, 6, 4, 4];
var result = array.reduce(function(hash){
return function(p,c,i){
hash[c] = (hash[c] || 0) + 1;
if(hash.prev && (hash.prev !== c || i == array.length - 1)) {
let obj= {};
obj[hash.prev] = hash[hash.prev];
delete hash[hash.prev];
p.push(obj);
}
hash.prev = c;
return p;
}
}(Object.create(null)),[]);
console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}
While Array.prototype.reduce is a nice function, it does have some compatibility issues.
Here is a solution using old school for loops:
var arr = [1, 1, 2, 1, 1, 1, 2, 3, 4, 4, 4, 6, 4, 4];
var results = [];
for (var indexA = 0; indexA < arr.length; indexA++) {
var a = arr[indexA];
if (results.length > 0) {
if (a == results[results.length - 1]["value"]) {
continue;
}
}
var r = { value: a, index: indexA, count: 0 };
for (var indexB = indexA; indexB < arr.length; indexB++) {
var b = arr[indexB];
if (a != b) {
break;
}
r.count++;
}
results.push(r);
}
console.log(results);
The posted solutions are fine but as noted by #Emil S. Jørgensen there might be compatibility issues using Array.reduce. Also, the suggested old school solution by #Emil S. Jørgensen uses two loops. If you want to have a slightly more efficient,simple and straightforward solution which will work in all browsers then use:
var arr = [1, 1, 2, 1, 1, 1, 2, 3, 4, 4, 4, 6, 4, 4];
var result = [];
var current = arr[0];
var count = 1;
for (var i = 1; i <= arr.length; i++)
{
if(arr[i] === current)
{
count+= 1;
}
else
{
var newObj = {};
newObj[current] = count;
result.push(newObj);
current = arr[i];
count = 1;
}
}
console.log(result); //prints the solution

Categories

Resources