如何减少具有重复值的数组?

时间:2019-03-19 23:58:26

标签: javascript arrays loops object duplicates

我有一个像这样的数组

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

5 个答案:

答案 0 :(得分:1)

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

通过使用地图提取来用唯一类型填充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);

答案 1 :(得分:1)

此解决方案不是减少操作,但返回的结果是相同的

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)

答案 2 :(得分:1)

以下是使用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;

答案 3 :(得分:1)

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

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

答案 4 :(得分: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);