1

I have an array which looks like this:

["1,8", "4,6,8", "8,9", "6,9"]

1/ I would like to turn it in to this

[1,8,4,6,8,8,9,6,9]

2/ I would then like to find matching values, by looking for the most number:

[8]

This first has been solved with this:

var carArray  = ["1,8", "4,6,8,7,7,7,7", "8,9", "6,9"];

//1) create single array
var arr = carArray.join().split(','); 

//2) find most occurring
var counts = {}; //object to hold count for each occurence    
var max = 0, maxOccurring;
arr.forEach(function(el){     
    var cnt = (counts[el] || 0); //previous count
    counts[el] = ++cnt;
    if(cnt > max && cnt > 1){ //only register if more than once (cnt>1)
        max=cnt;
        maxOccurring = el;
    }
});


if(maxOccurring){
    //there was an element more than once, maxOccuring contains that element
    setResult('Most occuring: ' + maxOccurring + ' (' + max + ' times)');
}
else{
    //3)/4) ???
    setResult('sorting?');
}

//below is only for test display purposes
function setResult(res){
    console.log(res);
}

3/ If the are no matching values like this

[1,8,4,6,5,7]

4/ Then I need to compare this array to another array, such as this

[6,7,4,1,2,8,9,5]

If the first number in <4> array above appears in <3> array, then get that number, ie in the above example I need to get 6. The <4> array will be static values and not change. The numbers is <3> will be dynamic.

EDIT Not the most elegant of answers, but I do have something working now. I didn't compare the original array directly with the second array, instead used simple if/else statements to do what I needed:

var carArray  = ["1,5", "4", "8,2", "3,9,1,1,1"];
//1) create single array
var arr = carArray.join().split(','); 

//2) find most occurring
var counts = {}; //object to hold count for each occurence    
var max = 0, maxOccurring;
arr.forEach(function(el){     
    var cnt = (counts[el] || 0); //previous count
    counts[el] = ++cnt;
    if(cnt > max && cnt > 1){ //only register if more than once (cnt>1)
        max=cnt;
        maxOccurring = el;
    }
});
if(maxOccurring){
    //there was an element more than once, maxOccuring contains that element
    console.log('Most occuring: ' + maxOccurring + ' (' + max + ' times)');
    console.log(maxOccurring);
}
else {
    // If not occuring, match from a list
    if(jQuery.inArray("6", arr) !== -1) { console.log('6'); }
    else if(jQuery.inArray("9", arr) !== -1) { console.log('9'); }
    else if(jQuery.inArray("7", arr) !== -1) { console.log('7'); }
    else if(jQuery.inArray("5", arr) !== -1) { console.log('5'); }
    else if(jQuery.inArray("4", arr) !== -1) { console.log('4'); }
    else if(jQuery.inArray("1", arr) !== -1) { console.log('1'); }
    else { console.log('not found'); }
}
4
  • 2
    What have you done so far? Commented Aug 21, 2015 at 7:38
  • 1
    In example 3, isn't 2 a matching value? How is it different from 8 in example 1? Commented Aug 21, 2015 at 7:42
  • Sorry I got that wrong and I can't seem to edit it. If there are no matching values to begin with, then I just need to sort in to unique order. Thanks ;) Commented Aug 21, 2015 at 7:54
  • What does "unique order" mean? Commented Aug 21, 2015 at 8:01

6 Answers 6

1

Example Fiddle

Step 1 is fairly easy by using javascript's join and split methods respectively:

var arr = carArray .join().split(',');

For step 2, several methods can be used, the most common one using an object and using the elements themselves as properties. Since you only need to get the most occurring value if there is a reoccurring value, it can be used in the same loop:

var counts = {}; //object to hold count for each occurence    
var max = 0, maxOccurring;
arr.forEach(function(el){     
    var cnt = (counts[el] || 0); //previous count
    counts[el] = ++cnt;
    if(cnt > max && cnt > 1){ //only register if more than once (cnt>1)
        max=cnt;
        maxOccurring = el;
    }
});

After the above, the variable maxOccurring will contain the reoccurring value (if any) and max will contain the times it occured

For step 4 the easiest way is to loop through the compare array and get the element that occurs in the input array:

var cmpArr = ['6','7','4','1','2','8','9','5'];
//find the first occurrence inside the cmpArr

res = function(){ for(var i= 0 ; i < cmpArr.length; i++){ if(arr.indexOf(cmpArr[i]) !== -1)return cmpArr[i];}}();  

The above uses an in place function which is called immediately to be able to use return. You could also just use a loop and assign res when found, then break from the loop.

Last update, an alternate fiddle where the above is converted to a single function: http://jsfiddle.net/v9hhsdny/5/

Sign up to request clarification or add additional context in comments.

3 Comments

This really helped me with this so far, thanks. The first part is working which is to look for numbers which appear more than once. The next part I have to find is when all the numbers are different, i'll update the question.
you're very welcome. I see the question is updated, but could you explain exactly how the unique order is determined in step 4?
OK thanks, have updated again to be more clear. I need to see if I have the first number from the second list. If I do I need to get that number, if I dont have the number I need to look for the next one in the second list.
0

Well first of all the following code results in four matching answers since the jQuery selectors are the same.

var questionAnswer1 = $(this).find('input[name=questionText]').val();
var questionAnswer2 = $(this).find('input[name=questionText]').val();
var questionAnswer3 = $(this).find('input[name=questionText]').val();
var questionAnswer4 = $(this).find('input[name=questionText]').val();

var carArray = [questionAnswer1, questionAnswer2, questionAnswer3, questionAnswer4];

You could use the eq(index) method of jQuery to select the appropriate element. However having 4 inputs with the same name is a bad practice.

Well lets say that the carArray has 4 different values which all consist out of comma separated numbers. You could then do the following:

var newArr = [];
carArray.forEach(function(e) {
    e.split(",").forEach(function(n) {
        newArr.push(n);
    });
});

Well then we got to find the most occurring number. JavaScript doesn't have any functions for that so we will have to find an algorithm for that. I found the following algorithm on this stackoverflow page

var count = function(ary, classifier) {
    return ary.reduce(function(counter, item) {
        var p = (classifier || String)(item);
        counter[p] = counter.hasOwnProperty(p) ? counter[p] + 1 : 1;
        return counter;
    }, {})
}

var occurances = count(newArr);

2 Comments

Thanks, you are right I overlooked the same value used for name=. I've since changed that. The values though come from different screens and will still produce ["1,8", "4,6,8", "8,9", "6,9"]. Any ideas though now to change to numbers?
You could use parseInt when you have splitted the numbers. newArr.push(parseInt(n));
0

It isn't clear to me what you're trying to do in step 3 and 4, so can't answer those at the moment.

var ary = ["1,8", "4,6,8", "8,9", "6,9"];

var splitted = ary.reduce(function(acc, item) {
        return acc.concat(item.split(','));
    }, []);

var occurences = splitted.reduce(function(acc, item) {
        if (!acc.hasOwnProperty(item)) acc[item] = 0;
        acc[item] += 1;
        return acc;
    },{}),
    biggest = Object.keys(occurences).reduce(function (acc, key) {
        if (occurences[key] > acc.occurences) {
            acc.name = key;
            acc.occurences = occurences[key];
        }
        return acc;
    },{'name':'none','occurences':0}).name;

Comments

0
var vals=["1,8", "4,6,8", "8,9", "6,9"];
// 1)  turn into number array
var arrNew=[];
for(var i=0; i<vals.length; i++)   
{ 
    arrLine=vals[i].split(",");
    for (var j=0;j<arrLine.length;j++) { arrNew.push (parseInt(arrLine[j])) }
}

//result: 
alert(arrNew.join(";");

// 2) find most common
var found=[];
for(var i=0; i<arrNew.length; i++) {
    // make an array of the number of occurrances of each value
    if (found["num"+newArray[i]]) {
        found["num"+newArray[i]] ++ ;
    } else {
        found["num"+newArray[i]]=1;
    }
}

var mostCommon={count:0,val:"ROGUE"};
for (x in found) {
    if (found[x] > mostCommon.count) {
        mostCommon.count=found[x].count;
        mostCommon.val=x;
    }
}

// result : 
alert(mostCommon.val);

//3) not quite sure what you meant there

// 4) unique values:
// at this point the 'found' list contains unique vals
var arrUnique=[];
for (x in found) {
    arrUnique.push[x];
}
// result :
alert(arrUnique.join(";"))


//sort:
arrUnique.sort(function(a, b){return a-b}); 

Comments

0

(This won't work in most browsers) but on a side note, when ES6 becomes widely supported, your solution could look like this:

var arr1 = ["1,8", "4,6,8", "8,9", "6,9"];
var arr2 = arr1.join().split(',');
var s = Array.from(new Set(arr2)); //Array populated by unique values, ["1", "8", "4", "6", "9"]

Thought you might like to see a glimpse of the future!

4 Comments

Thanks for this. I am building a web app for iPads only, does iOS support this?
@IanFraser Unfortunately not, but you should make a note of this if you wish to update it at a later time. You can periodically check the iOS compatibility table for ES6 to see when this will work in the future.
Didn't know about Set but this is great :)
@Nimrodx I can't wait til these features are widely supported, ES6 is a complete overhaul. Set is already pretty widely featured too!
0

1.

var orgArray = ['1,8', '4,6,8', '8,9', '6,9'];
var newArray = [];
for (var i in orgArray) {
  var tmpArray = orgArray[i].split(',');
  for (var j in tmpArray) {
    newArray.push(Number(tmpArray[j]));
  }
}

2.

var counts = {};
var most = null;
for (var i in newArray) {
  var num = newArray[i];
  if (typeof counts[num] === 'undefined') {
    counts[num] = 1;
  } else {
    ++(counts[num]);
  }
  if (most == null || counts[num] > counts[most]) {
    most = num;
  } else if (most != null && counts[num] === counts[most]) {
    most = null;
  }
}

I don't understand the question 3 and 4 (what "unique order" means) so I can't answer those questions.

1 Comment

Thanks, I have just updated my post. First part solved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.