combining duplicate key's values in JavaScript array

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"]}]

8 answers

  • answered 2021-05-15 18:28 AmD

    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();
    }
    

  • answered 2021-05-15 18:39 Ben Stephens

    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);

  • answered 2021-05-15 18:40 Kinglish

    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)

  • answered 2021-05-15 18:41 Ran Turner

    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)

  • answered 2021-05-15 19:59 MikeM

    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);

  • answered 2021-05-15 20:15 Senior Web Engineer

    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.

    const arr = [{
        somekey: "Some Value Pushed",
      },
      {
        somekey2: "Second Value2",
      },
      {
        somekey: "Some Value Pushed",
      },
      {
        somekey2: "Second Value3",
      },
      {
        somekey3: "",
      },
      {},
    ];
    
    const ans = arr.reduce(
      (prv, cur) => {
        Object.entries(cur).forEach(([key, v]) => key in prv ? prv[key].push(v) : (prv[key] = [v]));
        return prv;
      }, {}
    );
    
    console.log(ans);

  • answered 2021-05-15 20:54 M. Saudagar

    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)

  • answered 2021-05-15 22:22 M. Saudagar

    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)