2

I have an array of objects. Each object has an amount and value property. If an object has the same amount value I would like to add that value to that object.

Here's an example array:

const array = [
  {
    "key": 1,
    "amount": 11,
    "value": "were"
  },
  {
    "key": 2,
    "amount": 6,
    "value": "locomotives"
  },
  {
    "key": 3,
    "amount": 5,
    "value": "They"
  },
  {
    "key": 4,
    "amount": 5,
    "value": "with"
  },
  {
    "key": 5,
    "amount": 4,
    "value": "used"
  }
]

I would like to transform this to resemble this:

const array = [
  {
    "key": 1,
    "amount": 11,
    "value": "were"
  },
  {
    "key": 2,
    "amount": 6,
    "value": "locomotives"
  },
  {
    "key": 3,
    "amount": 5,
    "value": "They, width"
  },
  {
    "key": 5,
    "amount": 4,
    "value": "used"
  }
]

I've tried reduce and map but I can't seem to get it to join,

5
  • Both input and output look the same to me. Commented Mar 6, 2020 at 12:47
  • @customcommander "They" and "width" have the same "amount", and so are aggregated in the same object. Commented Mar 6, 2020 at 12:50
  • @customcommander correct - that's what I am trying to achieve Commented Mar 6, 2020 at 12:50
  • Ah right! I think you could mention the key you want to group by. Commented Mar 6, 2020 at 12:52
  • @RobGleeson I would approach the situation using a map, where the key could be the "amount" and the value would be an object like { key, value }. I would then iterate through the array, and fill the map according to the structure mentioned above. If you'd be interested, I can share the code for this. :) Commented Mar 6, 2020 at 12:52

5 Answers 5

1

I think should work with .reduce():

const array = [
  {
    "key": 1,
    "amount": 11,
    "value": "were"
  },
  {
    "key": 2,
    "amount": 6,
    "value": "locomotives"
  },
  {
    "key": 3,
    "amount": 5,
    "value": "They"
  },
  {
    "key": 4,
    "amount": 5,
    "value": "with"
  },
  {
    "key": 5,
    "amount": 4,
    "value": "used"
  }
];

const result = array.reduce((a, c) => {
  const found = a.find(e => e.amount === c.amount);  
  if (found) found.value = `${found.value}, ${c.value}`;
  return found ? a : a.concat(c);
}, []);

console.log(result);

I hope that helps!

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

Comments

1

You can use .reduce() with an ES6 Map by indexing by the amount value. If an object's amount value already exists within the map, you can update its value to include the current objects value. If the amount value isn't in the map, you can set it as a key and the current object as the value. Lastly, you can use Array.from() to get an array of object values from the iterator returned by .values()

const array = [ { "key": 1, "amount": 11, "value": "were" }, { "key": 2, "amount": 6, "value": "locomotives" }, { "key": 3, "amount": 5, "value": "They" }, { "key": 4, "amount": 5, "value": "with" }, { "key": 5, "amount": 4, "value": "used" } ];

const res = Array.from(array.reduce((m, o) => {
  const curr = m.get(o.amount);
  return m.set(o.amount, curr && {...curr, value: `${curr.value}, ${o.value}`} || o);
}, new Map).values());
console.log(res);

Comments

0

mine..

const array1 = 
      [ { key: 1, amount: 11, value: "were"        } 
      , { key: 2, amount:  6, value: "locomotives" } 
      , { key: 3, amount:  5, value: "They"        } 
      , { key: 4, amount:  5, value: "with"        } 
      , { key: 5, amount:  4, value: "used"        } 
      ] 


const array2 = array1.reduce((a,c)=>
                {
                let same = a.find(e=>e.amount===c.amount)
                if (same) same.value += ', '+c.value
                else a.push(c)
                return a
                },[])

console.log( array2 )

Comments

0

In each iteration of reduce method, we can add value if there is an already added value:

const result = array.reduce((a, c) => {
  a[c.amount] = a[c.amount] || c;
  if ((Object.keys(a).includes(c.amount.toString())) && (a[c.amount].value!= c.value))
      a[c.amount].value += ', ' + c.value;
  return a;
}, {});

An example:

const array = [
  {
    "key": 1,
    "amount": 11,
    "value": "were"
  },
  {
    "key": 2,
    "amount": 6,
    "value": "locomotives"
  },
  {
    "key": 3,
    "amount": 5,
    "value": "They"
  },
  {
    "key": 4,
    "amount": 5,
    "value": "with"
  },
  {
    "key": 5,
    "amount": 4,
    "value": "used"
  }
];

const result = array.reduce((a, c) => {
  a[c.amount] = a[c.amount] || c;
  if ((Object.keys(a).includes(c.amount.toString())) && (a[c.amount].value!= c.value))
      a[c.amount].value += ', ' + c.value;
  return a;
}, {});

console.log(result);

Comments

0

Use forEach loop and build an object. If the amount key already exist then append the value string.

const update = data => {
  const res = {};
  data.forEach(item => {
    res[item.amount] =
      item.amount in res
        ? {
            ...res[item.amount],
            value: `${res[item.amount].value}, ${item.value}`
          }
        : { ...item };
  });
  return Object.values(res);
};

const array = [
  {
    key: 1,
    amount: 11,
    value: "were"
  },
  {
    key: 2,
    amount: 6,
    value: "locomotives"
  },
  {
    key: 3,
    amount: 5,
    value: "They"
  },
  {
    key: 4,
    amount: 5,
    value: "with"
  },
  {
    key: 5,
    amount: 4,
    value: "used"
  }
];

console.log(update(array));

Comments

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.