How do I calculate the mode of an array - JavaScript? [duplicate] - javascript

This question already has answers here:
how to get mode in array
(8 answers)
Closed 2 years ago.
I am making a code that finds the mode of a set of numbers in an array (differenceArr). I almost cracked it, except there is one problem. Let me show you my code so far so you can understand:
var mapping = {};
var counter = 0;
for(var i = 0;i < differenceArr.length; i++){
if (!mapping[differenceArr[i]]) mapping[differenceArr[i]] = 0;
mapping[differenceArr[i]] += 1;
}
var z;
var toValidateModeJSONObj = mapping;
var max_of_difarray = Math.max.apply(Math, differenceArr);
var howManyActuallyExist = -1;
var modeArray = [];
for(var n = 0; n< max_of_difarray; n++){
var exists = toValidateModeJSONObj[differenceArr[n].toString()];
if(exists == undefined){
exists = false;
}else{
howManyActuallyExist++;
modeArray[howManyActuallyExist] ={theNumber: differenceArr[n].toString(), theValue: exists};
}
console.log(JSON.stringify(modeArray));
Now that I have everything in modeArray, I have to get which one has the biggest theValue in modeArray, and then I have to get the mode in a variable so I can return it. How do I do that? Anyone have any working code snippets?

Try this out :)
const getMode = (items) => {
// Go through the array
if (items.length === 0) return -1 // error
const store = {}
let maxCount = 0;
let maxIndex = -1;
items.forEach((item, index) => {
if (!store[item]) {store[item] = 0}
// update value
store[item] += 1
if (store[item] > maxCount) {
maxIndex = index
maxCount = store[item]
}
})
// NOTE: this code does not consider if there are two modes.
return items[maxIndex]
}
// ==========================
const getModeMoreThanOne = (items) => {
// Go through the array
if (items.length === 0) return -1 // error
const store = {}
let maxCount = 0
let maxIndex = -1
items.forEach((item, index) => {
if (!store[item]) {store[item] = 0}
// update value
store[item] += 1
if (store[item] > maxCount) {
maxIndex = index
maxCount = store[item]
}
})
const modes = Object.keys(store).filter(key => store[key] === maxCount)
return modes
}
getMode("abcdefababa".split("")) // 'a'
getModeMoreThanOne("abcdefabbaba".split("")) // ['a', 'b']

Related

Find Unique Number from array in JavaScript

Please let me know is this a best approach to find unique number from an array?
var singleNumber = function(nums) {
for (var i = 0; i < nums.length; i++) {
if (i === 0) {
nums[0] = 0 ^ nums[0];
/* console.log(nums[0]); */
} else {
nums[0] ^= nums[i];
/* console.log(nums[0]); */
}
}
console.log(nums[0]);
return nums[0];
};
singleNumber([2, 2, 3, 3, 4]);
If you have any better approach with this, help me out.
I've created two functions that return unique numbers from a passed array:
var getFirstUniqueNumber = function(nums) {
var number = null;
var map = {};
nums.forEach((val) => {
if (!map[val] && (number === null)) number = val;
if (map[val] && (number !== null)) number = null;
map[val] = true;
});
return number;
};
var getLastUniqueNumber = function(nums) {
var number = null;
var map = {};
nums.forEach((val) => {
if (!map[val]) number = val;
map[val] = true;
});
return number;
};
I've created a Fiddle here: https://jsfiddle.net/u88qgxrr/2/
They do what the name says, you probably want the last unique number!

Slice an array to multiple parts [duplicate]

This question already has answers here:
Split array into chunks
(73 answers)
Closed 6 years ago.
My example:
let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18];
let slice = (source, index) => source.slice(index, index + 4);
let length = arr.length;
let index = 0;
let result = [];
while (index < length) {
let temp = slice(arr, index);
result.push(temp);
index += 4;
}
console.log(result);
Logging:
[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18]]
I want to slice the array to multiple parts for per 4 items [1,2,3,4] [5,6,7,8]...
The code is working fine.
I have 2 questions:
1/. Is there another way to do that via using inline code? Ex: result = arr.slice(...)
2/. After I define:
let push = result.push;
why cannot I still use:
push(temp)
Error message:
Uncaught TypeError: Array.prototype.push called on null or undefined
UPDATE: I've updated the solution based on the answers. Hope it's helpful.
let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18];
let result = [];
arr.forEach((x,y,z) => !(y % 4) ? result.push(z.slice(y, y + 4)) : '');
console.log(result);
Logging:
[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18]]
A simple way to do it
var chunckArray = function(array, chunkCount){
var chunks = [];
while(array.length){
chunks.push(array.splice(0, chunkCount);
}
return chunks;
}
A non consumative way :
var chunckArray = function(array, chunkCount){
var chunks = [], i, j;
for (i = 0, j = array.length; i<j; i+= chunkCount) {
chunks.push(array.slice(i, i + chunkCount);
}
return chunks;
}
You can also do it using a for loop which will give you a same result:
let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18];
console.log(arr.length);
var result=[];
for(var i = 0; i < arr.length; i+=4) {
result=arr.slice(i, i+4);
console.log(result);
}
I've done this using a simple reduce (see plnkr):
let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18];
var counter = -1;
var result = arr.reduce((final, curr, i) => {
if (i % 4 === 0) {
final.push([curr])
counter++;
} else {
final[counter].push(curr);
}
return final;
}, []);
console.log(result);
You can tweak the 4 and substitute it with a variable chuckSize this will allow you to be able reapply to other things - you could also wrap this in a function with paramerters (array, chunkSize) if you wanted to

show most frequently occuring input value [duplicate]

var store = ['1','2','2','3','4'];
I want to find out that 2 appear the most in the array. How do I go about doing that?
I would do something like:
var store = ['1','2','2','3','4'];
var frequency = {}; // array of frequency.
var max = 0; // holds the max frequency.
var result; // holds the max frequency element.
for(var v in store) {
frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
if(frequency[store[v]] > max) { // is this frequency > max so far ?
max = frequency[store[v]]; // update max.
result = store[v]; // update result.
}
}
Solution with emphasis to Array.prototype.forEach and the problem of getting more than one key if the max count is shared among more items.
Edit: Proposal with one loop, only.
var store = ['1', '2', '2', '3', '4', '5', '5'],
distribution = {},
max = 0,
result = [];
store.forEach(function (a) {
distribution[a] = (distribution[a] || 0) + 1;
if (distribution[a] > max) {
max = distribution[a];
result = [a];
return;
}
if (distribution[a] === max) {
result.push(a);
}
});
console.log('max: ' + max);
console.log('key/s with max count: ' + JSON.stringify(result));
console.log(distribution);
arr.sort();
var max=0,result,freq = 0;
for(var i=0; i < arr.length; i++){
if(arr[i]===arr[i+1]){
freq++;
}
else {
freq=0;
}
if(freq>max){
result = arr[i];
max = freq;
}
}
return result;
Make a histogram, find the key for the maximum number in the histogram.
var hist = [];
for (var i = 0; i < store.length; i++) {
var n = store[i];
if (hist[n] === undefined) hist[n] = 0;
else hist[n]++;
}
var best_count = hist[store[0]];
var best = store[0];
for (var i = 0; i < store.length; i++) {
if (hist[store[i]] > best_count) {
best_count = hist[store[i]];
best = store[i];
}
}
alert(best + ' occurs the most at ' + best_count + ' occurrences');
This assumes either there are no ties, or you don't care which is selected.
Another ES6 option. Works with strings or numbers.
function mode(arr) {
const store = {}
arr.forEach((num) => store[num] ? store[num] += 1 : store[num] = 1)
return Object.keys(store).sort((a, b) => store[b] - store[a])[0]
}
If the array is sorted this should work:
function popular(array) {
if (array.length == 0) return [null, 0];
var n = max = 1, maxNum = array[0], pv, cv;
for(var i = 0; i < array.length; i++, pv = array[i-1], cv = array[i]) {
if (pv == cv) {
if (++n >= max) {
max = n; maxNum = cv;
}
} else n = 1;
}
return [maxNum, max];
};
popular([1,2,2,3,4,9,9,9,9,1,1])
[9, 4]
popular([1,2,2,3,4,9,9,9,9,1,1,10,10,10,10,10])
[10, 5]
This version will quit looking when the count exceeds the number of items not yet counted.
It works without sorting the array.
Array.prototype.most= function(){
var L= this.length, freq= [], unique= [],
tem, max= 1, index, count;
while(L>= max){
tem= this[--L];
if(unique.indexOf(tem)== -1){
unique.push(tem);
index= -1, count= 0;
while((index= this.indexOf(tem, index+1))!= -1){
++count;
}
if(count> max){
freq= [tem];
max= count;
}
else if(count== max) freq.push(tem);
}
}
return [freq, max];
}
//test
var A= ["apples","oranges","oranges","oranges","bananas",
"bananas","oranges","bananas"];
alert(A.most()) // [oranges,4]
A.push("bananas");
alert(A.most()) // [bananas,oranges,4]
I solved it this way for finding the most common integer
function mostCommon(arr) {
// finds the first most common integer, doesn't account for 2 equally common integers (a tie)
freq = [];
// set all frequency counts to 0
for(i = 0; i < arr[arr.length-1]; i++) {
freq[i] = 0;
}
// use index in freq to represent the number, and the value at the index represent the frequency count
for(i = 0; i < arr.length; i++) {
freq[arr[i]]++;
}
// find biggest number's index, that's the most frequent integer
mostCommon = freq[0];
for(i = 0; i < freq.length; i++) {
if(freq[i] > mostCommon) {
mostCommon = i;
}
}
return mostCommon;
}
This is my solution.
var max_frequent_elements = function(arr){
var a = [], b = [], prev;
arr.sort();
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
var max = b[0]
for(var p=1;p<b.length;p++){
if(b[p]>max)max=b[p]
}
var indices = []
for(var q=0;q<a.length;q++){
if(b[q]==max){indices.push(a[q])}
}
return indices;
};
All the solutions above are iterative.
Here's a ES6 functional mutation-less version:
Array.prototype.mostRepresented = function() {
const indexedElements = this.reduce((result, element) => {
return result.map(el => {
return {
value: el.value,
count: el.count + (el.value === element ? 1 : 0),
};
}).concat(result.some(el => el.value === element) ? [] : {value: element, count: 1});
}, []);
return (indexedElements.slice(1).reduce(
(result, indexedElement) => (indexedElement.count > result.count ? indexedElement : result),
indexedElements[0]) || {}).value;
};
It could be optimized in specific situations where performance is the bottleneck, but it has a great advantage of working with any kind of array elements.
The last line could be replaced with:
return (indexedElements.maxBy(el => el.count) || {}).value;
With:
Array.prototype.maxBy = function(fn) {
return this.slice(1).reduce((result, element) => (fn(element) > fn(result) ? element : result), this[0]);
};
for clarity
If the array contains strings try this solution
function GetMaxFrequency (array) {
var store = array;
var frequency = []; // array of frequency.
var result; // holds the max frequency element.
for(var v in store) {
var target = store[v];
var numOccurences = $.grep(store, function (elem) {
return elem === target;
}).length;
frequency.push(numOccurences);
}
maxValue = Math.max.apply(this, frequency);
result = store[$.inArray(maxValue,frequency)];
return result;
}
var store = ['ff','cc','cc','ff','ff','ff','ff','ff','ff','yahya','yahya','cc','yahya'];
alert(GetMaxFrequency(store));
A fairly short solution.
function mostCommon(list) {
var keyCounts = {};
var topCount = 0;
var topKey = {};
list.forEach(function(item, val) {
keyCounts[item] = keyCounts[item] + 1 || 1;
if (keyCounts[item] > topCount) {
topKey = item;
topCount = keyCounts[item];
}
});
return topKey;
}
document.write(mostCommon(['AA', 'AA', 'AB', 'AC']))
This solution returns an array of the most appearing numbers in an array, in case multiple numbers appear at the "max" times.
function mode(numbers) {
var counterObj = {};
var max = 0;
var result = [];
for(let num in numbers) {
counterObj[numbers[num]] = (counterObj[numbers[num]] || 0) + 1;
if(counterObj[numbers[num]] >= max) {
max = counterObj[numbers[num]];
}
}
for (let num in counterObj) {
if(counterObj[num] == max) {
result.push(parseInt(num));
}
}
return result;
}

Sort array of strings into array of objects

Okay, so I've been working on a sort function for my application, and I've gotten stuck.
Here's my fiddle.
To explain briefly, this code starts with an array of strings, serials, and an empty array, displaySerials:
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"];
var displaySerials = [];
The aim of these functions is to output displaySerials as an array of objects with two properties: beginSerial and endSerial. The way that this is intended to work is that the function loops through the array, and tries to set each compatible string in a range with each other, and then from that range create the object where beginSerial is the lowest serial number in range and endSerial is the highest in range.
To clarify, all serials in a contiguous range will have the same prefix. Once that prefix is established then the strings are broken apart from the prefix and compared and sorted numerically.
So based on that, the desired output from the array serials would be:
displaySerials = [
{ beginSerial: "BHU-008", endSerial: "BHU-011" },
{ beginSerial: "BHU-000", endSerial: "BHU-002" },
{ beginSerial: "TYU-969", endSerial: "TYU-970" }
]
I've got it mostly working on my jsfiddle, the only problem is that the function is pushing one duplicate object into the array, and I'm not sure how it is managing to pass my checks.
Any help would be greatly appreciated.
Marc's solution is correct, but I couldn't help thinking it was too much code. This is doing exactly the same thing, starting with sort(), but then using reduce() for a more elegant look.
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"]
serials.sort()
var first = serials.shift()
var ranges = [{begin: first, end: first}]
serials.reduce(mergeRange, ranges[0])
console.log(ranges) // the expected result
// and this is the reduce callback:
function mergeRange(lastRange, s)
{
var parts = s.split(/-/)
var lastParts = lastRange.end.split(/-/)
if (parts[0] === lastParts[0] && parts[1]-1 === +lastParts[1]) {
lastRange.end = s
return lastRange
} else {
var newRange = {begin: s, end: s}
ranges.push(newRange)
return newRange
}
}
I've got a feeling that it's possible to do it without sorting, by recursively merging the results obtained over small pieces of the array (compare elements two by two, then merge results two by two, and so on until you have a single result array). The code wouldn't look terribly nice, but it would scale better and could be done in parallel.
Nothing too sophisticated here, but it should do the trick. Note that I'm sorting the array from the get-go so I can reliably iterate over it.
Fiddle is here: http://jsfiddle.net/qyys9vw1/
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"];
var myNewObjectArray = [];
var sortedSerials = serials.sort();
//seed the object
var myObject = {};
var previous = sortedSerials[0];
var previousPrefix = previous.split("-")[0];
var previousValue = previous.split("-")[1];
myObject.beginSerial = previous;
myObject.endSerial = previous;
//iterate watching for breaks in the sequence
for (var i=1; i < sortedSerials.length; i++) {
var current = sortedSerials[i];
console.log(current);
var currentPrefix = current.split("-")[0];
var currentValue = current.split("-")[1];
if (currentPrefix === previousPrefix && parseInt(currentValue) === parseInt(previousValue)+1) {
//sequential value found, so update the endSerial with it
myObject.endSerial = current;
previous = current;
previousPrefix = currentPrefix;
previousValue = currentValue;
} else {
//sequence broken; push the object
console.log(currentPrefix, previousPrefix, parseInt(currentValue), parseInt(previousValue)+1);
myNewObjectArray.push(myObject);
//re-seed a new object
previous = current;
previousPrefix = currentPrefix;
previousValue = currentValue;
myObject = {};
myObject.beginSerial = current;
myObject.endSerial = current;
}
}
myNewObjectArray.push(myObject); //one final push
console.log(myNewObjectArray);
I would use underscore.js for this
var bSerialExists = _.findWhere(displaySerials, { beginSerial: displaySettings.beginSerial });
var eSerialExists = _.findWhere(displaySerials, { endSerial: displaySettings.endSerial });
if (!bSerialExists && !eSerialExists)
displaySerials.push(displaySettings);
I ended up solving my own problem because I was much closer than I thought I was. I included a final sort to get rid of duplicate objects after the initial sort was finished.
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"];
var displaySerials = [];
var mapSerialsForDisplay = function () {
var tempArray = serials;
displaySerials = [];
for (var i = 0; i < tempArray.length; i++) {
// compare current member to all other members for similarity
var currentSerial = tempArray[i];
var range = [currentSerial];
var displaySettings = {
beginSerial: currentSerial,
endSerial: ""
}
for (var j = 0; j < tempArray.length; j++) {
if (i === j) {
continue;
} else {
var stringInCommon = "";
var comparingSerial = tempArray[j];
for (var n = 0; n < currentSerial.length; n++) {
if (currentSerial[n] === comparingSerial[n]) {
stringInCommon += currentSerial[n];
continue;
} else {
var currentRemaining = currentSerial.replace(stringInCommon, "");
var comparingRemaining = comparingSerial.replace(stringInCommon, "");
if (!isNaN(currentRemaining) && !isNaN(comparingRemaining) && stringInCommon !== "") {
range = compareAndAddToRange(comparingSerial, stringInCommon, range);
displaySettings.beginSerial = range[0];
displaySettings.endSerial = range[range.length - 1];
var existsAlready = false;
for (var l = 0; l < displaySerials.length; l++) {
if (displaySerials[l].beginSerial == displaySettings.beginSerial || displaySerials[l].endSerial == displaySettings.endSerial) {
existsAlready = true;
}
}
if (!existsAlready) {
displaySerials.push(displaySettings);
}
}
}
}
}
}
}
for (var i = 0; i < displaySerials.length; i++) {
for (var j = 0; j < displaySerials.length; j++) {
if (i === j) {
continue;
} else {
if (displaySerials[i].beginSerial === displaySerials[j].beginSerial && displaySerials[i].endSerial === displaySerials[j].endSerial) {
displaySerials.splice(j, 1);
}
}
}
}
return displaySerials;
}
var compareAndAddToRange = function (candidate, commonString, arr) {
var tempArray = [];
for (var i = 0; i < arr.length; i++) {
tempArray.push({
value: arr[i],
number: parseInt(arr[i].replace(commonString, ""))
});
}
tempArray.sort(function(a, b) {
return (a.number > b.number) ? 1 : ((b.number > a.number) ? -1 : 0);
});
var newSerial = {
value: candidate,
number: candidate.replace(commonString, "")
}
if (tempArray.indexOf(newSerial) === -1) {
if (tempArray[0].number - newSerial.number === 1) {
tempArray.unshift(newSerial)
} else if (newSerial.number - tempArray[tempArray.length - 1].number === 1) {
tempArray.push(newSerial);
}
}
for (var i = 0; i < tempArray.length; i++) {
arr[i] = tempArray[i].value;
}
arr.sort();
return arr;
}
mapSerialsForDisplay();
console.log(displaySerials);
fiddle to see it work
Here's a function that does this in plain JavaScript.
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"];
function transformSerials(a) {
var result = []; //store array for result
var holder = {}; //create a temporary object
//loop the input array and group by prefix
a.forEach(function(val) {
var parts = val.split('-');
var type = parts[0];
var int = parseInt(parts[1], 10);
if (!holder[type])
holder[type] = { prefix : type, values : [] };
holder[type].values.push({ name : val, value : int });
});
//interate through the temp object and find continuous values
for(var type in holder) {
var last = null;
var groupHolder = {};
//sort the values by integer
var numbers = holder[type].values.sort(function(a,b) {
return parseInt(a.value, 10) > parseInt(b.value, 10);
});
numbers.forEach(function(value, index) {
if (!groupHolder.beginSerial)
groupHolder.beginSerial = value.name;
if (!last || value.value === last + 1) {
last = value.value;
groupHolder.endSerial = value.name;
if (index === numbers.length - 1) {
result.push(groupHolder);
}
}
else {
result.push(groupHolder);
groupHolder = {};
last = null;
}
});
}
return result;
}
console.log(transformSerials(serials));
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

Get the item that appears the most times in an array

var store = ['1','2','2','3','4'];
I want to find out that 2 appear the most in the array. How do I go about doing that?
I would do something like:
var store = ['1','2','2','3','4'];
var frequency = {}; // array of frequency.
var max = 0; // holds the max frequency.
var result; // holds the max frequency element.
for(var v in store) {
frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
if(frequency[store[v]] > max) { // is this frequency > max so far ?
max = frequency[store[v]]; // update max.
result = store[v]; // update result.
}
}
Solution with emphasis to Array.prototype.forEach and the problem of getting more than one key if the max count is shared among more items.
Edit: Proposal with one loop, only.
var store = ['1', '2', '2', '3', '4', '5', '5'],
distribution = {},
max = 0,
result = [];
store.forEach(function (a) {
distribution[a] = (distribution[a] || 0) + 1;
if (distribution[a] > max) {
max = distribution[a];
result = [a];
return;
}
if (distribution[a] === max) {
result.push(a);
}
});
console.log('max: ' + max);
console.log('key/s with max count: ' + JSON.stringify(result));
console.log(distribution);
arr.sort();
var max=0,result,freq = 0;
for(var i=0; i < arr.length; i++){
if(arr[i]===arr[i+1]){
freq++;
}
else {
freq=0;
}
if(freq>max){
result = arr[i];
max = freq;
}
}
return result;
Make a histogram, find the key for the maximum number in the histogram.
var hist = [];
for (var i = 0; i < store.length; i++) {
var n = store[i];
if (hist[n] === undefined) hist[n] = 0;
else hist[n]++;
}
var best_count = hist[store[0]];
var best = store[0];
for (var i = 0; i < store.length; i++) {
if (hist[store[i]] > best_count) {
best_count = hist[store[i]];
best = store[i];
}
}
alert(best + ' occurs the most at ' + best_count + ' occurrences');
This assumes either there are no ties, or you don't care which is selected.
Another ES6 option. Works with strings or numbers.
function mode(arr) {
const store = {}
arr.forEach((num) => store[num] ? store[num] += 1 : store[num] = 1)
return Object.keys(store).sort((a, b) => store[b] - store[a])[0]
}
If the array is sorted this should work:
function popular(array) {
if (array.length == 0) return [null, 0];
var n = max = 1, maxNum = array[0], pv, cv;
for(var i = 0; i < array.length; i++, pv = array[i-1], cv = array[i]) {
if (pv == cv) {
if (++n >= max) {
max = n; maxNum = cv;
}
} else n = 1;
}
return [maxNum, max];
};
popular([1,2,2,3,4,9,9,9,9,1,1])
[9, 4]
popular([1,2,2,3,4,9,9,9,9,1,1,10,10,10,10,10])
[10, 5]
This version will quit looking when the count exceeds the number of items not yet counted.
It works without sorting the array.
Array.prototype.most= function(){
var L= this.length, freq= [], unique= [],
tem, max= 1, index, count;
while(L>= max){
tem= this[--L];
if(unique.indexOf(tem)== -1){
unique.push(tem);
index= -1, count= 0;
while((index= this.indexOf(tem, index+1))!= -1){
++count;
}
if(count> max){
freq= [tem];
max= count;
}
else if(count== max) freq.push(tem);
}
}
return [freq, max];
}
//test
var A= ["apples","oranges","oranges","oranges","bananas",
"bananas","oranges","bananas"];
alert(A.most()) // [oranges,4]
A.push("bananas");
alert(A.most()) // [bananas,oranges,4]
I solved it this way for finding the most common integer
function mostCommon(arr) {
// finds the first most common integer, doesn't account for 2 equally common integers (a tie)
freq = [];
// set all frequency counts to 0
for(i = 0; i < arr[arr.length-1]; i++) {
freq[i] = 0;
}
// use index in freq to represent the number, and the value at the index represent the frequency count
for(i = 0; i < arr.length; i++) {
freq[arr[i]]++;
}
// find biggest number's index, that's the most frequent integer
mostCommon = freq[0];
for(i = 0; i < freq.length; i++) {
if(freq[i] > mostCommon) {
mostCommon = i;
}
}
return mostCommon;
}
This is my solution.
var max_frequent_elements = function(arr){
var a = [], b = [], prev;
arr.sort();
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
var max = b[0]
for(var p=1;p<b.length;p++){
if(b[p]>max)max=b[p]
}
var indices = []
for(var q=0;q<a.length;q++){
if(b[q]==max){indices.push(a[q])}
}
return indices;
};
All the solutions above are iterative.
Here's a ES6 functional mutation-less version:
Array.prototype.mostRepresented = function() {
const indexedElements = this.reduce((result, element) => {
return result.map(el => {
return {
value: el.value,
count: el.count + (el.value === element ? 1 : 0),
};
}).concat(result.some(el => el.value === element) ? [] : {value: element, count: 1});
}, []);
return (indexedElements.slice(1).reduce(
(result, indexedElement) => (indexedElement.count > result.count ? indexedElement : result),
indexedElements[0]) || {}).value;
};
It could be optimized in specific situations where performance is the bottleneck, but it has a great advantage of working with any kind of array elements.
The last line could be replaced with:
return (indexedElements.maxBy(el => el.count) || {}).value;
With:
Array.prototype.maxBy = function(fn) {
return this.slice(1).reduce((result, element) => (fn(element) > fn(result) ? element : result), this[0]);
};
for clarity
If the array contains strings try this solution
function GetMaxFrequency (array) {
var store = array;
var frequency = []; // array of frequency.
var result; // holds the max frequency element.
for(var v in store) {
var target = store[v];
var numOccurences = $.grep(store, function (elem) {
return elem === target;
}).length;
frequency.push(numOccurences);
}
maxValue = Math.max.apply(this, frequency);
result = store[$.inArray(maxValue,frequency)];
return result;
}
var store = ['ff','cc','cc','ff','ff','ff','ff','ff','ff','yahya','yahya','cc','yahya'];
alert(GetMaxFrequency(store));
A fairly short solution.
function mostCommon(list) {
var keyCounts = {};
var topCount = 0;
var topKey = {};
list.forEach(function(item, val) {
keyCounts[item] = keyCounts[item] + 1 || 1;
if (keyCounts[item] > topCount) {
topKey = item;
topCount = keyCounts[item];
}
});
return topKey;
}
document.write(mostCommon(['AA', 'AA', 'AB', 'AC']))
This solution returns an array of the most appearing numbers in an array, in case multiple numbers appear at the "max" times.
function mode(numbers) {
var counterObj = {};
var max = 0;
var result = [];
for(let num in numbers) {
counterObj[numbers[num]] = (counterObj[numbers[num]] || 0) + 1;
if(counterObj[numbers[num]] >= max) {
max = counterObj[numbers[num]];
}
}
for (let num in counterObj) {
if(counterObj[num] == max) {
result.push(parseInt(num));
}
}
return result;
}

Categories