Reputation: 181
I want to join values of array by key to another array. For example, for below input array
[['value', 'element1'],['value', 'element2'], ['value1', 'element1'], ['value', null]]
I would like to have an output
[['value', 'element1', 'element2'], ['value1', 'element1']]
Is there any way to achieve this?
Upvotes: 3
Views: 475
Reputation: 63524
A simple reduce
on the data can solve this. Often you would use an object to map the values to keys, and then map out the key/values to a new array, but in this case you can just use an index to target a nested array in the returned array instead.
var out = data.reduce(function (p, c) {
// the key is the first array element, the value the second
// and i is the index of the nested array in the returned array
var key = c[0],
val = c[1],
i = +key.substr(5) || 0;
// if the nested array in the returned array doesn't exist
// create it as a new array with the key as the first element
p[i] = p[i] || [key];
// if the value is not null, push it to the correct
// nested array in the returned array
if (val) p[i].push(val);
return p;
}, []);
Upvotes: 1
Reputation: 3142
var ref = [['value', 'element1'],['value', 'element2'], ['value1', 'element1'], ['value', null]],
results = [[], []];
ref.filter(function (e) {
for (var i = 0; i < e.length; i++) {
if (e[i] && results[0].indexOf(e[i]) === -1) {
results[0].push(e[i]);
} else if (e[i]) {
results[1].push(e[i]);
}
}
});
Upvotes: 0
Reputation: 6052
Do the trick in Map-reduce approach
function groupMap(array){
var list = array.reduce(accumulate,{});
return Object.keys(list).map(function(k){
return [k].concat(list[k])
})
}
function accumulate(result,a){
var vector = a.slice(1); // Vector of the values
if (result.hasOwnProperty(a[0])){ // Already have the key in the result?
if (vector.length>0 && vector[0])
result[a[0]] = result[a[0]].concat(vector)
}
else{ // new key
if (vector.length>0 && vector[0])
result[a[0]] = vector;
else
result[a[0]] = []
}
return result;
}
var array = [['value', 'element1'],['value', 'element2'], ['value1', 'element1'], ['value', null]];
var result = groupMap(array);
console.log(result); // Check the output
How it works
Upvotes: 0
Reputation: 877
arr = [['value', 'element1'],['value', 'element2'], ['value1', 'element1'], ['value', null]];
obj = {}
arr.forEach(function(item) {
var key = item[0];
if (key) {
obj[key] = obj[key] || [];
item.forEach(function(val, index) {
if (index != 0 && val) {
obj[key].push(val);
}
});
}
});
console.log(Object.keys(obj).map(function(key) {
obj[key].unshift(key);
return obj[key];
}));
Upvotes: 0
Reputation: 171669
Can use a temporary object to hold the first elements as keys. then loop through that object at the end to build the resultant arrays
var tmp = {}
var data = [['value', 'element1'],['value', 'element2'], ['value1', 'element1'], ['value', null]] ;
data.forEach(function(elem){
if(!tmp.hasOwnProperty(elem[0]) && elem[1]){
tmp[elem[0]] = elem;
}else if(elem[1]){
tmp[elem[0]].push(elem[1]);
}
});
var results = Object.keys(tmp).map(function(key){
return tmp[key];
});
document.getElementById('pre').innerHTML = JSON.stringify(results)
<pre id="pre"></pre>
Upvotes: 0
Reputation: 1465
Try it.
var data="";
var j=0;
var i=0;
var array1 = [['value', 'element1'],['value', 'element2'], ['value1', 'element1'], ['value', null]];
var array2 = [];
$.each(array1, function(index,value){
if(value[1] != null)
{
if(data == value[0])
{
j++;
array2[i][j] = value[1];
}
else
{
i++;
j = 1;
data = value[0];
array2[i] = [];
array2[i][0] = value[0];
array2[i][j] = value[1];
}
}
});
console.log(array2);
=>output.
[['value', 'element1', 'element2'], ['value1', 'element1']]
Upvotes: 0