鍍金池/ 問答/網(wǎng)絡(luò)安全  HTML/ 一個數(shù)組中包含多個對象,怎么把所有對象中某個屬性相同的對象進(jìn)行去重?

一個數(shù)組中包含多個對象,怎么把所有對象中某個屬性相同的對象進(jìn)行去重?

如題,形入

arr = [
    {
        a: '1',
        b: 'q1'
    },
    {
        a: '2',
        b: 'q2'
    },
    {
        a: '1',
        b: 'q3'
    },
    {
        a: '1',
        b: 'q4'
    },
    {
        a: '2',
        b: 'q5'
    },
    {
        a: '3',
        b: 'q6'
    }
]

處理這樣的數(shù)據(jù)使特定屬性相同(例如這里的屬性‘a(chǎn)’)的對象去重,并讓序號在后的對象覆蓋序號在前的除‘a(chǎn)’以外的所有屬性,如下形式:

arr = [
    {
        a: '1',
        b: 'q4'
    },
    {
        a: '2',
        b: 'q5'
    },
    {
        a: '3',
        b: 'q6'
    }
]

補(bǔ)充一下,每個對象里的屬性不止a和b,有很多個,能確定的是每個對象里的有的屬性名都是一樣的

回答
編輯回答
奧特蛋

更新:

既然確定屬性列表都一樣,那不考慮值嵌套的情況下:

        // 提取出每個對象的 `a` 值 [1, 2, 1, 1, 2, 3]
let O = arr.map(a => a['a'])
        // 對 `a` 值進(jìn)行一次統(tǒng)計(jì)整理,形如 { a值: 最后一次在 arr 中出現(xiàn)的位置 }
        // [{'1': 3}, {'2': 4}, {'3': 5}]
        .reduce((o, k, i) => [o[k] = i, o][1], {}) 
        
// 對剛才的整理結(jié)果再進(jìn)行一次整理
Object.keys(O).map(k => {
    // 此處的 k 就是剛才 { a值: 最后一次在 arr 中出現(xiàn)的位置 } 里的 a 值
    // 構(gòu)造一個新的 object
    let o = {a: k};
    // O[k] 就是取出 k 所對應(yīng)的 a 值最后一次在 arr 中出現(xiàn)的位置
    // arr[O[k]] 就是 k 所對應(yīng)的 a 值最后一次在 arr 中出現(xiàn)時所處的對象
    // 對 arr[O[k]] 遍歷一次鍵
    Object.keys(arr[O[k]])
         // 把 arr[O[k]] 上的鍵值挨個復(fù)制到 o 上
         // Ps. 突然發(fā)現(xiàn)剛才沒有在遍歷時跳過 a 的值,此處修改一下,原答案里就不改了。
        .forEach(key => o[key] = key === 'a' ? o[key] : arr[O[k]][key]);
    // 返回構(gòu)造好的新對象    
    return o;
})

原答案:


let O = arr.map(a => a['a']).reduce((o, k, i) => [o[k] = i, o][1], {})
Object.keys(O).map(k => {
    // 如果是要覆蓋多個屬性,那就這里用擴(kuò)展庫的 clone 方法(考慮到嵌套)把原來的復(fù)制一份然后修改 a 的值
    // 如果不嵌套,那就
    // let o = {a: k};
    // Object.keys(arr[O[k]]).forEach(key => o[key] = arr[O[k]][key]);
    return {a: k, b: arr[O[k]]['b']}
})
2017年1月9日 20:25
編輯回答
六扇門
let arr = [
  { a: '1', b: 'q1' },
  { a: '2', b: 'q2' },
  { a: '1', b: 'q3' },
  { a: '1', b: 'q4' },
  { a: '2', b: 'q5' },
  { a: '3', b: 'q6' }
]
let b = []
let Fun = (arr, type, cType) => {
  arr.map((v, i) => {
    if (b.length === 0) {
      b.push(v)
    } else {
      let isAdd = true
      b.forEach((v1, i1) => {
        if (v[type] === v1[type]) {
          isAdd = false
          v1[cType] = v[cType]
        }
      })
      if (isAdd) b.push(v)
    }
  })
}
Fun(arr, 'a', 'b')
2017年10月23日 23:53
編輯回答
青檸
var arr = [
        {
            a: '1',
            b: 'q1'
        },
        {
            a: '2',
            b: 'q2'
        },
        {
            a: '1',
            b: 'q3'
        },
        {
            a: '1',
            b: 'q4'
        },
        {
            a: '2',
            b: 'q5'
        },
        {
            a: '3',
            b: 'q6'
        }
    ];
    var c=arr.reverse().filter(function(item,index){
        var _index=arr.findIndex(function(_item){
            return item.a == _item.a;
        });
        return index == _index;
    });
    c.reverse();
    console.log(c);
2017年3月2日 14:49