-1

I have an Array that contain some keys/values one of the values is an array I want combining the value of array from all recorded that have same key in my Array.

Below is an Simple Example to demonstrate, I am not able to construct its logic so seeking help in building a logic to it.

[{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}]

I want Result Like,

[{"somekey":["Some Value Pushed","Second Value"]}]
Sam
  • 1,106
  • 10
  • 14
  • Does this answer your question? [Most efficient method to groupby on an array of objects](https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects) – pilchard May 15 '21 at 19:15
  • Downvoted because of lack of clarity and lack of response to the answers given. The only answer that has been upvoted doesn't even return an array as required. Please add some more objects with different keys to your Array and Result so your requirements are comprehensible. – MikeM May 17 '21 at 20:01

8 Answers8

1

The reduce() function of Array Object in JavaScript can merge any array into a single Object. I wrote a single-line code to solve this problem. I updated result with the array.

 const arr = [{
        somekey: "Some Value Pushed",
      },
      {
        somekey2: "Second Value2",
      },
      {
        somekey: "Some Value Pushed",
      },
      {
        somekey2: "Second Value3",
      },
      {
        somekey3: "",
      },
      {},
    ];

    const ansObj = arr.reduce(
      (prv, cur) => {
        Object.entries(cur).forEach(([key, v]) => key in prv ? prv[key].push(v) : (prv[key] = [v]));
        return prv;
      }, {}
    )
    const ansArray = Object.entries(ansObj).map(([key, value])=>({[key]:value}));
    

    console.log(ansArray);
Reinis
  • 477
  • 1
  • 5
  • 13
0

You can try something like this:

var array = [{
  name: "foo1",
  value: "val1"
}, {
  name: "foo1",
  value: ["val2", "val3"]
}, {
  name: "foo2",
  value: "val4"
}];

var output = [];

array.forEach(function(item) {
  var existing = output.filter(function(v, i) {
    return v.name === item.name;
  });
  if (existing.length) {
    var existingIndex = output.indexOf(existing[0]);
    output[existingIndex].value = output[existingIndex].value.concat(item.value);
  } else {
    if (typeof item.value === 'string')
      item.value = [item.value];
    output.push(item);
  }
});

Or, another option using Lodash

function mergeNames (arr) {
    return _.chain(arr).groupBy('name').mapValues(function (v) {
        return _.chain(v).pluck('value').flattenDeep();
    }).value();
}
AmD
  • 399
  • 2
  • 12
0

Maybe something like:

const data = [
  {"somekey":"Some Value Pushed"},
  {"somekey":"Second Value", "otherkey": 1},
  {"otherkey": 2}
];

const merge_and_group = (obj1, obj2) =>
  Object.entries(obj2).reduce(
    (acc, [key, val]) => {
      acc[key] ??= [];
      acc[key].push(val);
      return acc;
    },
    obj1
  );

const res = data.reduce(merge_and_group, {});

console.log(res);
Ben Stephens
  • 3,303
  • 1
  • 4
  • 8
0

const arr = [{
  "somekey": "Some Value Pushed"
}, {
  "somekey2": "Second Value2"
}, {
  "somekey": "Some Value Pushed"
}, {
  "somekey2": "Second Value3"
}]

const newarr = {}
arr.forEach(obj => {
  for (const [key, value] of Object.entries(obj)) {
    if (newarr[key]) newarr[key].push(value)
    else newarr[key] = [value]
  }
})

console.log(newarr)
Kinglish
  • 23,358
  • 3
  • 22
  • 43
0

Array.prototype.reduce() is a possible option.

the reduce() method executes a reducer function which is provided as an input on each element of the array and returning a single output value.

const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}];

const res = array.reduce((acc, el) => {
  const [key, value] = Object.entries(el)[0];
  (acc[key] || (acc[key] = [])).push(value);
  return acc;
}, {});

console.log(res)
Ran Turner
  • 14,906
  • 5
  • 47
  • 53
0

Assuming each element of your array is an object with a single key.

const array = [
  { somekey: "Some Value Pushed" },
  { somekey: "Second Value" },
  { foo: "bar" },
  { foo: "baz" },
  { somekey: "Third Value" },
];

const result = [];

array.forEach(el => {
  let [key, value] = Object.entries(el)[0];
  for (let el of result) if (key in el) {
    el[key].push(value);
    return;
  } 
  result.push({ [key]: [value] });
});

console.dir(result);
MikeM
  • 13,156
  • 2
  • 34
  • 47
0

If your array has only "somekey" as keys then you can use map method as following:

const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}];

const valuesArray = array.map(obj => obj.somekey);

result = [{"somekey":valuesArray}];

console.log(result)
M. Saudagar
  • 1
  • 1
  • 1
0

If your array has other keys along with "somekey" and you like to separate values corresponding to only "somekey" then try the following:

const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}, {"otherkey":"other Value"}];

const filteredArray = array.filter((obj) => {
  return  "somekey" in obj
}, []);

const valuesArray = filteredArray.map(obj => obj.somekey);

result = [{"somekey":valuesArray}];

console.log(result)
M. Saudagar
  • 1
  • 1
  • 1