3

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?

2
  • you could try basic iteration over array and manipulate it. Commented Jan 12, 2016 at 8:09
  • if you are doing lot of these sorts of manipulations I'd recommend using lodash lodash.com/docs#groupBy Commented Jan 12, 2016 at 8:17

6 Answers 6

1

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

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

Comments

0

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']]

1 Comment

Try it without using jQuery.
0

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>

Comments

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

Comments

0

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.

Comments

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

1 Comment

What if there's a value2?

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.