Reputation: 4361
The question doesn't make much sense but not sure how to word it without an example. If someone can word it better, feel free to edit it.
Let's say I have an array of arrays such as this:
[ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ]
I would like the output to be:
['a', 'a', 'b', 'b', 'b', 'c', 'd', 'e']
Not sure if there is an easy way to do this in javascript/jquery/underscore. One way I could think of is to look through each of these arrays and count up the number of times each element shows up and keep track of the maximum amount of times it shows up. Then I can recreate it. But that seems pretty slow considering that my arrays can be very large.
Upvotes: 0
Views: 65
Reputation: 272096
You need to:
Following code shows a rough outline of the process. Remember to replace .forEach
and for..in
with appropriate code:
var input = [['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e']],
inputCount = {};
input.forEach(function(inner) {
var innerCount = {};
inner.forEach(function(value) {
innerCount[value] = innerCount[value] ? innerCount[value] + 1 : 1;
});
var value;
for (value in innerCount) {
inputCount[value] = inputCount[value] ? Math.max(inputCount[value], innerCount[value]) : innerCount[value];
}
});
console.log(inputCount);
// Object {a: 2, b: 3, c: 1, d: 1, e: 1}
Upvotes: 1
Reputation: 4361
After messing around, I found a solution but not sure if I like it enough to use. I would probably use it if I can't think of another one.
I would use underscorejs countBy to get the count of all the elements.
var array = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
var count = _.map(array, function(inner) {
return _.countBy(inner, function(element) {
return element;
});
});
var total = {};
_.each(_.uniq(_.flatten(array)), function(element) {
var max = _.max(count, function(countedElement) {
return countedElement[element];
});
total[element] = max[element];
});
console.log(total); // {a: 2, b: 3, c: 1, d: 1, e: 1}
Then I would recreate the array with that total.
Upvotes: 1
Reputation: 3142
Not the most efficient solution but it should describe you the process:
var big = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
function map(arr){
var map = {}
for (var i=arr.length-1; i>-1; i--){
if(arr[i] in map) map[arr[i]]++;
else map[arr[i]] = 1;
}
return map;
}
function reduce(matrix){
var arrMap = {};
for (var i=matrix.length-1; i>-1; i--){
var arrRes = map(matrix[i]);
for (var key in arrRes){
if( !arrMap[key] || arrMap[key] < arrRes[key])
arrMap[key] = arrRes[key];
}
}
return arrMap;
}
function calc(matrix){
var res = [],
arrMap = reduce(matrix);
for (var key in arrMap){
while(arrMap[key] > 0 ){
res.push(key);
arrMap[key]--;
}
}
return res;
}
console.log(calc(big));
// Array [ "e", "b", "b", "b", "a", "a", "d", "c" ]
Upvotes: 0
Reputation: 71384
Here is example of simple nested loop approach:
var input = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
var countMap = {};
// iterate outer array
for (i=0; i < input.length; i++) {
// iterate inner array
for (j=0; j < input[i].length; j++) {
// increment map counter
var value = input[i][j];
if (countMap[input[i][j]] === undefined) {
countMap[value] = 1;
} else {
countMap[value]++;
}
}
}
console.log(countMap); // output such as {'a':2, 'b':4, 'c':1, 'd':1, 'e':1}
Upvotes: 0