This question already has answers here:
Get the element with the highest occurrence in an array
(42 answers)
Closed 4 years ago.
I am a beginner in JavaScript and I was trying to write code for finding the mode. My code is running but it can find the mode only when it is written consecutively. But when there is an array like this a = [1,2,3,4,5,2], it can not find the mode.
As I am a beginner I do not want to write anything complex but want to learn it in the simplest way. Can anyone please help me in this purpose?
list = [1,2,3,4,5,6,7,7]
var empty = []
i = 0
max = 0
while (i<list.length){
if (list[i]==list[i+1]){
empty = list[i]
i += 1
}else{
i +=1
}
}
document.write(empty)
Your code assumes that the parameter array is pre-sorted which is a risky and limiting assumption, and only appears to work on sorted arrays (counterexample: [1,1,1,7,7] incorrectly reports 7 as the mode).
If you wish you persist with this approach, you're on the right track, but you'll need to keep track of the current/best streaks, current/best elements and perform a final check for longest streak before returning the result:
var mode = a => {
a = a.slice().sort((x, y) => x - y);
var bestStreak = 1;
var bestElem = a[0];
var currentStreak = 1;
var currentElem = a[0];
for (let i = 1; i < a.length; i++) {
if (a[i-1] !== a[i]) {
if (currentStreak > bestStreak) {
bestStreak = currentStreak;
bestElem = currentElem;
}
currentStreak = 0;
currentElem = a[i];
}
currentStreak++;
}
return currentStreak > bestStreak ? currentElem : bestElem;
};
console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));
Having said that, sorting is a non-linear operation, so I recommend trying another approach.
The idea is to keep a count of occurrences for each item in the array using an object, then take the element with the highest count. I used reduce to perform these two operations:
const mode = a =>
Object.values(
a.reduce((count, e) => {
if (!(e in count)) {
count[e] = [0, e];
}
count[e][0]++;
return count;
}, {})
).reduce((a, v) => v[0] < a[0] ? a : v, [0, null])[1];
;
console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));
Or, the same thing, written without reduce for readability:
const mode = a => {
const count = {};
a.forEach(e => {
if (!(e in count)) {
count[e] = 0;
}
count[e]++;
});
let bestElement;
let bestCount = 0;
Object.entries(count).forEach(([k, v]) => {
if (v > bestCount) {
bestElement = k;
bestCount = v;
}
});
return bestElement;
};
console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));
Note that these approaches don't choose the same mode in case of ties. You may wish to add an array to keep track of all modes, or change your algorithm to pick the first or last occurring mode to suit your needs.
use a hash
list = [1,2,3,4,5,6,7,7]
counts = {}
list.forEach(function(e) {
if(counts[e] === undefined) {
counts[e] = 0
}
counts[e] += 1
})
which results in this:
{1:1,2:1,3:1,4:1,5:1,6:1,7:2}
This related question deals with finding the max and min in a hash, which is essentially what you do at the end of this.
Fast way to get the min/max values among properties of object
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am new to javascript. I am having a little issue here.
Is javascript if / else statement different than other languages (c++, java, python)?
Here is the issue that I am having.
if else statement only accepts i == 0 and i == 1 into my new array from myArray.
Why am I not be able to separate other elements into my new array? I used myArray for an example. In my real problem, I wouldn't know how many elements I have. That is why I have set up variables threetimes and increaseByThree. I am just trying to separate name, zip code, and amount into the different array by using a for loop.
var nameArray = [], zipCodeArray = [], totalAmountArray = [];
var threeTimes = 3;
var increaseByThree = 0;
var myArray = ["Eric ", "94990", "540", "Sam ", "303030", "350"];
for(var i = 0; i < myArray.length; i++) {
threeTimes += 3;
increaseByThree += 3;
if(i == threeTimes || i == 0) {
nameArray.push(myArray[i]);
} else if(i == increaseByThree || i == 1) {
zipCodeArray.push(myArray[i]);
} else {
totalAmountArray.push(myArray[i]);
}
}
console.log(nameArray)
console.log(zipCodeArray)
console.log(totalAmountArray)
Assuming your array will be in the format [a0, b0, c0, ....., aN, bN, cN] where N is the number of 'entries' - 1; you could simplify your logic that you determine where to put the value by:
const myArray = ["Eric ", "94990", "540", "Sam ", "303030", "350"];
const nameArray = [], zipCodeArray = [], totalAmountArray = [];
for(var i = 0; i < myArray.length; i++) {
switch (i % 3) {
case 0:
nameArray.push(myArray[i]);
break;
case 1:
zipCodeArray.push(myArray[i]);
break;
case 2:
totalAmountArray.push(myArray[i]);
break;
}
}
console.log(nameArray)
console.log(zipCodeArray)
console.log(totalAmountArray)
This will work for any size array and cuts out the need for the unnecessary variables and if-else blocks. Here is a helpful link for javascript's switch block
(https://www.w3schools.com/js/js_switch.asp) which are much cleaner as opposed to if-else blocks and show the intent more clearly in this case.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Question: How can I elegantly compare an array of strings to another array of strings thus returning an array of non-matching strings
var master = ['1','2','3','4']
var versioned = ['1a','2','3b','4']
var errorLog = []
var count = 0;
//this for loop doesn't work :(
for(var i = 0; i < versioned.length - 1; ++i ){
for(var j = 0; j < master.length -1; ++j){
if(versioned[i] === master[j]){
console.log('cleared');
}
if(count === master.length){
errorLog.push(versioned[i]);
}
}
}
loop will return ['1a', '3b'];
I feel like filter() or map() or reduce() will do this but I'm unable to wrap my brain around this properly.
var master = ['1','2','3','4'];
var versioned = ['1a','2','3b','4'];
function diff(needle, haystack){
return needle.filter(function(item){
return !~haystack.indexOf(item);
});
}
console.log(diff(versioned, master)); //["1a", "3b"];
~ NOTing any number equals -(x + 1). so ~-1 becomes 0, which is the only falsy.
~master.indexOf(item) is the same as master.indexOf(item) !== -1
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I would like to create a JSON object inside a for loop using javascript. I am expecting an result something like this:
{
"array":[
{
"value1":"value",
"value2":"value"
},
{
"value1":"value",
"value2":"value"
}
]
}
Can somebody help me on how to achieve this result in javascript ?
Instead of creating the JSON in the for-loop, create a regular JavaScript object using your for-loops and use JSON.stringify(myObject) to create the JSON.
var myObject = {};
for(...) {
myObject.property = 'newValue';
myObject.anotherProp = [];
for(...) {
myObject.anotherProp.push('somethingElse');
}
}
var json = JSON.stringify(myObject);
var loop = [];
for(var x = 0; x < 10; x++){
loop.push({value1: "value_a_" + x , value2: "value_b_" + x});
}
JSON.stringify({array: loop});
This code produces what you need:
var result = {"array": []};
for(var i = 0; i < 2; i++){
var valueDict = {};
for(var j = 0; j < 2; j++){
valueDict["value" + (j+1).toString()] = "value";
}
result["array"].push(valueDict);
}
It uses the push function to add items to the list, and the indexer [] notation notation to modify the entries on the object prototype.
Hope it helps,
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have a small script that should detect duplicate elements in an array of fields on a form.
function dupes() {
var unique = [];
//Loop through array of fields to get entered values
for (i = 0; i <= 9; i++) {
unique[i] = Number(document.getElementById('proj' + i).value);
}
unique.sort();
//Now compare the array values. If there are any duplicates, throw an error
for (i = 1; i <= 9; i++) {
if (unique[i] == unique[i - 1]) {
document.getElementById('errormsg').innerHTML = 'duplicated values!';
return false;
}
}
}
There are ten of these "proj" fields (proj0 - proj9), and I have an onClick event assigned to call this function. If there are any duplicate values, the span 'errormsg' is supposed to display an error, but it's not working. What might I be missing?
//Check for duplicate project numbers
function errorCheck() {
var unique = [];
//Loop through array of fields to get entered values
for (i = 0; i <= 9; i++) {
var currentValue = Number(document.getElementById('projNo' + i).value);
if(unique.indexOf(currentValue)!=-1)
{
document.getElementById('projError').innerHTML = 'duplicated values!';
return false;
}
unique[i]=currentValue;
}
return true;
}
FiddleDEMO
It first checks whether a value is already in the array by using unique.indexOf(currentValue). This function returns the index of the searched element and returns -1 if it is not found.
If it was not found, it adds it to the array and goes to the next one.
Edit:
If you want to reset the error message when you submit again and there are no more duplicates, don't forget to reset it before return true; like so:
document.getElementById('projError').innerHTML = 'no duplicates ;)';
This will detect the duplicate values :
var arr= [];
//Loop through array of fields to get entered values
for (i = 0; i <= 9; i++) {
arr.push(Number(document.getElementById('proj' + i).value));
}
function dupes(arr) { // pass the array to find dupes
var i, len=arr.length, unique= [], obj={};
for (i=0;i<len;i++) {
obj[arr[i]]=0;
}
for (i in obj) {
unique.push(i);
}
if(unique.length != arr.length) {
document.getElementById('errormsg').innerHTML = 'duplicated values!';
}
}
dupes(arr);