【问题标题】:duplicates for array of objects into organized data structure将对象数组复制到有组织的数据结构中
【发布时间】:2021-05-16 01:26:17
【问题描述】:

我有一个这样的数组:

let obj = [
    {
        id: 1,
        name: 'bob'
    },
        {
        id: 2,
        name: 'bob'
    },
        {
        id: 3,
        name: 'karl'
    },
        {
        id: 4,
        name: 'joe'
    },
        {
        id: 5,
        name: 'joe'
    },    {
        id: 6,
        name: 'rick'
    },
    
];

我需要编写一些 javascript 代码来解析数组并处理重复的名称。

我想要的结果是:

let obj = [
    {
        id: [1,2],
        name: 'bob'
    },
    {
        id: 3,
        name: 'karl'
    },
        {
        id: [4,5],
        name: 'joe'
    },
    {
        id: 6,
        name: 'rick'
    },
];

谁能帮忙?

【问题讨论】:

  • 非分组的 id 是否需要独立出现(即不在数组中)?如果它们也可以在数组中,那么这个问题将回答您的问题:Group array items using object

标签: javascript arrays object ecmascript-6


【解决方案1】:

您可以使用reducefind 轻松实现此结果。如果现有元素是array,那么您需要将其推送到数组中,否则创建一个数组并将现有元素与新的id一起推送到数组中

let obj = [
  {
    id: 1,
    name: "bob",
  },
  {
    id: 2,
    name: "bob",
  },
  {
    id: 3,
    name: "karl",
  },
  {
    id: 4,
    name: "joe",
  },
  {
    id: 5,
    name: "joe",
  },
  {
    id: 6,
    name: "rick",
  },
];

const result = obj.reduce((acc, curr) => {
  const { id, name } = curr;
  const findEl = acc.find((o) => o.name === name);
  if (findEl) {
    if (Array.isArray(findEl.id)) {
      findEl.id.push(id);
    } else {
      findEl.id = [findEl.id, id];
    }
  } else {
    acc.push({ id, name });
  }
  return acc;
}, []);

console.log(result);

您可以通过引入字典来提高其时间复杂度,并且无需每次都在reduce 中查找元素。但是这里的顺序可以改变result里面的对象

let obj = [
  {
    id: 1,
    name: "bob",
  },
  {
    id: 2,
    name: "bob",
  },
  {
    id: 3,
    name: "karl",
  },
  {
    id: 4,
    name: "joe",
  },
  {
    id: 5,
    name: "joe",
  },
  {
    id: 6,
    name: "rick",
  },
];

const dict = {};
obj.forEach((obj) => {
  const { id, name } = obj;
  if (dict[name]) {
    if (Array.isArray(dict[name])) {
      dict[name].push(id);
    } else {
      dict[name] = [dict[name], id];
    }
  } else {
    dict[name] = id;
  }
});

const result = Object.entries(dict).map(([name, id]) => ({ name, id }));

console.log(result);

【讨论】:

    【解决方案2】:

    Array.prototype.reduce() 在这种情况下很有用。

    let obj = [{
        id: 1,
        name: 'bob'
      },
      {
        id: 2,
        name: 'bob'
      },
      {
        id: 3,
        name: 'karl'
      },
      {
        id: 4,
        name: 'joe'
      },
      {
        id: 5,
        name: 'joe'
      }, {
        id: 6,
        name: 'rick'
      },
    ];
    const mergeObjectByValue = (objArray) => {
      const newObjs = objArray.reduce((prev, {
        name,
        id
      }) => {
        (name in prev) ? prev[name].push(id): prev[name] = [id]
        return prev;
      }, {})
      return Object.entries(newObjs).map(([name, ids]) => ({
        name,
        id: ids.length > 1 ? ids : ids[0],
      }))
    }
    console.log(mergeObjectByValue(obj))

    【讨论】:

      猜你喜欢
      • 2015-01-06
      • 2012-07-22
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 2016-03-31
      • 1970-01-01
      • 2015-12-16
      • 2014-12-13
      相关资源
      最近更新 更多