【问题标题】:How to reduce an array with duplicate value?如何减少具有重复值的数组?
【发布时间】:2019-08-10 14:39:31
【问题描述】:

我有一个这样的数组

let oldArray=[
    {type:16,img:['1']},
    {type:16,img:['2']},
    {type:16,img:['3']},
    {type:17,img:['4']}
]

如果类型相同,我想连接值。 我想要的结果是:

let newArray=[
    {type:16,img:['1','2','3']},
    {type:17,img:['4']}
]

我尝试使用reduce函数:

    oldArray.reduce((acc,cur,idx,src)=>{
if(cur.type===a[idx+1].type){
    cur.img.concat(a[idx+1].img);
    acc.push(cur)
} else {
    acc.push(a[idx+1])
}
    return acc

},[])

好像有错误 任何人都可以帮忙吗?谢谢。


Bibberty 方案的替代方案:flatMap 比reduce 清晰得多

let newArray = [...new Set(oldArray.map(e => e.type))]
                                    .map(e => {
                                        return {
                                            type: e,
                                            img: (oldArray.filter(i => i.type === e).map(x => x.img)).reduce((acc,cur,idx,src)=>{
                                                let length=src.length
                                                let tep=cur.concat(src[idx+1]);
                                                src[idx+1]=tep


                                                return src[idx=length-1]
                                            },[])
                                        }
                                    });

    console.log(newArray);

【问题讨论】:

  • 搜索如何在数组上执行“groupBy”

标签: javascript arrays loops object duplicates


【解决方案1】:

你可以使用reduce:

let oldArray = [{type: 16,img: ['1']},{type: 16,img: ['2']},{type: 16,img: ['3']},{type: 17,img: ['4']}];

let newArray = oldArray.reduce((acc, curr) => {
  acc.some(({
    type
  }) => type == curr.type) ? acc.find(({
    type
  }) => type == curr.type).img.push(curr.img[0]) : acc.push(curr);
  return acc;
}, []);

console.log(newArray);

【讨论】:

  • 这个解决方案使用最少的代码,并且非常容易理解。这就是我要找的。谢谢。
  • 不用担心@MINGWU,总是很乐意提供帮助。
【解决方案2】:

我们先使用 Set,然后使用地图。

通过使用地图提取来填充唯一类型。 我们包装在[] 中给我们一个数组,然后我们重新map 来构建我们的对象。 然后映射重建我们的对象并注意使用filtermap 从原始主机数组中获取img 值。

let oldArray=[
    {type:16,img:['1']},
    {type:16,img:['2']},
    {type:16,img:['3']},
    {type:17,img:['4']}
]

let newArray = [...new Set(oldArray.map(e => e.type))]
                .map(e => {
                  return {
                    type: e,
                    img: oldArray.filter(i => i.type === e).flatMap(x => x.img)
                  }
                });
  
console.log(newArray);

【讨论】:

  • 嗨,毕伯蒂,感谢您的回答。但是,结果与我想要的结果有点不同。根据您的结果,图像是 "img":[ ['1'],['2'],['3'] ] 。我想要'img':['1','2','3']。你的解决方案真的启发了我,我在你的函数之上添加了一个 reduce 函数。谢谢。
  • 已更正为你所需要的,刚刚添加flatMap
【解决方案3】:

这个解决方案不是reduce,但是你要找的返回结果是一样的

let oldArray = [
    {type:16,img:['1']},
    {type:16,img:['2']},
    {type:16,img:['3']},
    {type:17,img:['4']}
];

const transitoryMap = new Map();
for (const item of oldArray) {
    if (!transitoryMap.has(item.type)) {
        transitoryMap.set(item.type, [item.img[0]])
    } else {
        const value = transitoryMap.get(item.type)
        value.push(item.img[0])
        transitoryMap.set(item.type, value)
    }
}
    
const newArray = [];
for (const item of transitoryMap.keys()) {
    newArray.push({type:item,img:transitoryMap.get(item)})
}

console.log(newArray)

【讨论】:

    【解决方案4】:

    这是一个使用reduce 的示例。我添加了一个tracker 来跟踪newArray 中的类型。

    let oldArray = [
        {type:16,img:['1']},
        {type:16,img:['2']},
        {type:16,img:['3']},
        {type:17,img:['4']}
    ];
    
    oldArray.reduce((a,c)=>{
        let index = a.tracker.indexOf(c.type);
        if(index === -1) {
            a.tracker.push(c.type);
            a.newArray.push({...c, img:[...c.img]});
        } else {
            a.newArray[index].img.push(...c.img);
        }
        return a;
    },{tracker:[],newArray:[]}).newArray;
    

    【讨论】:

      【解决方案5】:

      您可能需要考虑将处理分解为单独的简单步骤,例如:

      1. 使用适当的数据创建一个展平对象。
      2. 用所需结构构建一个新数组。

      这不仅可以让您的代码保持简单,还可以让您专注于代码实际执行的操作,而不是代码执行任务的方式。

      var oldArray=[
          {type:16,img:['1']},
          {type:16,img:['2']},
          {type:16,img:['3']},
          {type:17,img:['4']}
      ]
      
      flattenMyObject = (arr) =>
          arr.reduce((accum, current) => {
              !!accum[current.type] ? accum[current.type].push(...current.img) : accum[current.type] = current.img;
              return accum;
          }, {});
      
      buildNewArray = (type) => {
          return {type: type, img: flattenedObject[type] }
      }
      
      Object
        .keys(flattenMyObject(oldArray))
        .map(buildNewArray);
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-19
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        • 2021-09-29
        • 1970-01-01
        • 1970-01-01
        • 2017-10-19
        相关资源
        最近更新 更多