I am trying to find the dominant element of an array. My idea is to scan the original array and put every individual element in another array. If there is already the element I increase a counter. When counter>Array.length/2 then it is the dominant.
This should work with any array.
my effort so far
function mainFunc() {
var result = 0;
var myArray=[4,5,6,4,2,4,5,6,7];
//result = test(myArray);
//alert("{ " + myArray + " } --> " + result);
}
function test(A) {
var tempArray = new Array;
for(var i=0;i<A.length;i++){
// 1. check if A[i] exists in tempArray
for(var j=0;j<tempArray.length;j++){
if(A[i]==tempArray[j])
{
}
}
// 2. If A[i] exists, increase counter
if(A[i]!=tempArray[])
Yes but the most common number may not be as common as half of them.
This is my effort and it finds the Mode
var i,j=0,finds=0,found;
var array = [1,4,2,3,4,1,4,2,4,4];
var temparray = new Array();
var counter = new Array();
function mode(){
for(i in array){
found=false;
for(j in temparray){
if(temparray[j]==array[i]){
counter[j]++;
found=true;}
}
if(found==false){
// if array[i] not found in temparray add it and increment the number of finds
temparray[finds]=array[i];
counter[finds]=1;
finds++;}
}
alert("variants found "+finds);
}
mode();
var highestIndex=0;
for(j=0;j<finds;j++){
if(counter[j]>=counter[highestIndex]){
highestIndex=j;}
}
See http://javascriptexample.net/extobjects83.php for code to find the mode that returns the value in an array (in case two or more numbers all occur the same number of times and more than any other number)
I propose this two lines script with a backreference regular expression
Code:
<script type="text/javascript">
//array to test
var arr=[1,41,222,33,40,18,22,41,2,2,41,42,27,41,58];
var lgt=0,nmb='',str=arr.sort().join(',').replace(/(,\d+)(\1+)/g,
function(a,b){var m;if (lgt<(m=a.length/b.length)) {lgt=m;nmb=b.substr(1)}});
alert('This number '+nmb+' appaers '+lgt+' times');
</script>
Last edited by 007julien; 12-01-2012 at 09:11 PM..
Well, (,\d) means "find a comma followed y one or more digits."
So it will match ",2" or ",41".
The (\1+) means "find the same thing matched by (,\d) one or more times.
So if you have ",2,2,2" that expression will first find ",2" and then see that there are two more occurrences of ",2" and end up matching all of ",2,2,2".
The only flaw in this code is that if NO string is found more than once, it will report back with [b[This number appaers 0 times[/b] (of course, the word should be "appears").
It also doesn't fulfill the requirement that the number be found more than half the time, but that's easy to do in a separate test.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
An alert(arr.sort().join(',')) give the string 1,18,2,2,22,222,27,33,40,41,41,41,41,42,58 which is an alphanumeric sort (sort(function(a,b){return a-b}) will assume a numeric increasing sort).
The \1+ after the first sub-pattern (,\d+) in the regular expression /(,\d+)(\1+)/g is a back-reference (1 for first sub-pattern) which allows to match all repeated set of one comma followed by one or more digits.
Then the anonymous function is called only for the duplicated numbers
The first argument a is the matched pattern (for example ,2,2 and b the first sub-pattern (the first curly bracket : ,2 in this case). The count of repetitions is also a.length/b.length, we do not use the replace function (See this page for further explanations) but define lgt (for lengthsQuotient) and nmb (for one «dominant» number).
NB : Its easy to define lgt=1 and nmb=arr[0] (with a nmb=+b.substr(1) to store a number) to replace a «This number appaers 0 times» by a better «This number 1 appears 1 time» with an alert('This number '+nmb+' appears '+lgt+' time'+(1<lgt?'s':'');
It is also possible to define the half-length of the array and test only the larger values.
This script can certainly be improved. Especially, with a (,[^,]+) instead of (,\d+) to work with all kind of comma separated values to find duplicates elements...
Apologies English is not my mother tongue
Last edited by 007julien; 12-01-2012 at 11:14 PM..
Though the code is flawed in another way: If there are two sets of numbers with the same count, it only finds the first such. This, too, could be fixed.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
var arr=[1,41,222,33,41,41,41,40,41,18,41,41,41,22,41,2,2,41,42,27,41,58];
var dominant=null,halfLength=arr.length/2,str=arr.sort().join(',').replace(/(,\d+)(\1+)(?=,)/g,
function(a,b){if (halfLength<=a.length/b.length) {dominant=+b.substr(1)}});
var msg=dominant?'Dominant number : '+dominant:'No dominant number !'
alert(msg);
EDIT : A new corrections repetition followed by a comma or a word boundary. An assertion like (\1+)(?=,|\b) matches a repetition followed by a comma or a word boundary, but does not include the comma in the match. There is never two dominant numbers !
Last edited by 007julien; 12-02-2012 at 12:03 AM..
Reason: complements