Home > Software engineering >  How to summarize object and array in JavaScript
How to summarize object and array in JavaScript

Time:09-22

I am trying to put together an object where some of this information was covered.

const tests = [
    {
        id: 1,
        name: 'taro',
        designId: 1,
        designName: 'design1'
    },
    {
        id: 1,
        name: 'taro',
        designId: 2,
        designName: 'design2'
    },
    {
        id: 2,
        name: 'Bob',
        designId: 3,
        designName: 'design3'
    },
    {
        id: 2,
        name: 'Bob',
        designId: 4,
        designName: 'design4'
    },
];

I want to set the following expectations.

result = [
  {
    id: 1,
    name: 'taro',
    designs: [
        { designId: 1, designName: 'design1' },
        { designId: 2, designName: 'design2' }
    ]
  },
  {
    id: 2,
    name: 'Bob',
    designs: [
        { designId: 3, designName: 'design3' },
        { designId: 4, designName: 'design4' }
    ]
  }
]

I have tried using lodash groupby as something I have tried, but I am struggling because I can't get rid of the extra properties.

const result = _.chain(tests)
    .groupBy('id')
    .map((value, key) => ({ id: key, designs: value }))
    .value();

CodePudding user response:

Using reduce and findIndex:

const tests = [
  {
    id: 1,
    name: 'taro',
    designId: 1,
    designName: 'design1'
  },
  {
    id: 1,
    name: 'taro',
    designId: 2,
    designName: 'design2'
  },
  {
    id: 2,
    name: 'Bob',
    designId: 3,
    designName: 'design3'
  },
  {
    id: 2,
    name: 'Bob',
    designId: 4,
    designName: 'design4'
  }
]

const arr = tests.reduce((acc, curr) => {
  const findIdx = acc.findIndex(x => x.name === curr.name)
  const design = { designId: curr.designId, designName: curr.designName }

  if (findIdx === -1) {
    acc.push({ id: curr.id, name: curr.name, designs: [design] })
  } else {
    acc[findIdx].designs.push(design)
  }

  return acc
}, [])

console.log(arr)

CodePudding user response:

You can use Array.prototype.reduce() combined with Object.values():

const tests = [{id: 1,name: 'taro',designId: 1,designName: 'design1',},{id: 1,name: 'taro',designId: 2,designName: 'design2',},{id: 2,name: 'Bob',designId: 3,designName: 'design3',},{id: 2,name: 'Bob',designId: 4,designName: 'design4'}]

const result = Object.values(tests.reduce((a, { id, name, ...rest }) => {
  a[id] = a[id] || { id, name, designs: [] }
  a[id].designs.push({ ...rest })
  return a
}, {}))

console.log(result)

CodePudding user response:

You can easily achieve the result efficiently using Map

const tests = [
  {
    id: 1,
    name: "taro",
    designId: 1,
    designName: "design1",
  },
  {
    id: 1,
    name: "taro",
    designId: 2,
    designName: "design2",
  },
  {
    id: 2,
    name: "Bob",
    designId: 3,
    designName: "design3",
  },
  {
    id: 2,
    name: "Bob",
    designId: 4,
    designName: "design4",
  },
];

const map = new Map();
tests.forEach(({ id, name, ...rest }) =>
  map.has(id)
    ? map.get(id).designs.push(rest)
    : map.set(id, { id, name, designs: [rest] })
);

const result = [...map.values()];

console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }

  • Related