Lukaszaq
Lukaszaq

Reputation: 181

Join value of js array by key

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

Answers (6)

Andy
Andy

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;
}, []);

DEMO

Upvotes: 1

n1kkou
n1kkou

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

TaoPR
TaoPR

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

  • Your array is "reduced" by accumulating the values of each key in the array. Where the key is represented by the first element.
  • The reduced result is the JSON object.
  • Then "map" that object back to an array.
  • Done.

Upvotes: 0

UtsavShah
UtsavShah

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

charlietfl
charlietfl

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

msthakur0064
msthakur0064

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

Related Questions