javascript - Array deduplication problem
女神的闺蜜爱上我
女神的闺蜜爱上我 2017-06-28 09:24:12
0
9
623

Suppose there is an object array

arr=[
    {
    id:1,
    content:'a'
    },{
    id:2,
    content:'b'
    },{
    id:2,
    content:'c'
    },{
    id:3,
    content:'d'
    },{
    id:3,
    content:'e'
    },{
    id:3,
    content:'f'
    },{
    id:3,
    content:'g'
    },{
    id:4,
    content:'h'
    },
]

I want to remove the same id and keep the last item of each id

arr=[
    {
    id:1,
    content:'a'
    },{
    id:2,
    content:'c'
    },{
    id:3,
    content:'g'
    },{
    id:4,
    content:'h'
    },
]

Is there any better way? .

女神的闺蜜爱上我
女神的闺蜜爱上我

reply all(9)
漂亮男人

By convention, ES6 code

const result = arr.reduce((r, t) => {
    // 在结果中查找 index,
    // 如果找到,更新该位置的对象引用
    // 找到则加一个
    var i = r.findIndex(m => m.id === t.id);
    if (i >= 0) {
        r[i] = t;
    } else {
        r.push(t);
    }
    return r;
}, []);

There is a problem here, findIndex is not supported by at least two browsers, so if it is not supported, you have to write one yourself

Array.prototype.findIndex = Array.prototype.findIndex || function(predicate) {
    for (let i = 0; i < this.length; i++) {
        if (predicate(this[i])) {
            return i;
        }
    }
    return -1;
};

Other solutions

Classic solution, use Map

Because id is not a string, ES6’s Map class is used. When the amount of data is large, using a lookup table can significantly improve efficiency compared to linear search in a list.

const result = arr
    .reduce((m, t) => {
        const { map, list } = m;
        var index = map.get(t.id);
        if (index >= 0) {
            list[index] = t;
        } else {
            map.set(t.id, list.length);
            list.push(t);
        }
        return m;
    }, {
        map: new Map(),
        list: []
    })
    .list;

In fact, you can also use objects instead of maps, at least in this use case there will be no problem. Because there are no es6 features, we simply use es5 syntax. The code structure and logic are the same as the above paragraph

var result = arr
    .reduce(function(m, t) {
        var index = m.map[t.id];
        if (index >= 0) {
            m.list[index] = t;
        } else {
            m.map[t.id] = m.list.length;
            m.list.push(t);
        }
        return m;
    }, {
        map: {},
        list: []
    })
    .list;

Weird solution, using integer id

Because it is an integer id, you can directly put it in the array according to this id. If the same ID is encountered, it will be replaced directly. If the ids are not consecutive, you need to filter out the empty elements at the end

var result = arr
    .reduce(function(r, t) {
        r[t.id] = t;
        return r;
    }, [])
    .filter(function(t) { return t; });

There is another problem with this solution. It cannot maintain the order of the elements of the original array. Then someone will definitely think that the solution using Map can also reduce the code into similar code without making it so complicated. Of course, it may also lose the original order

const map = arr
    .reduce((m, t) => {
        m.set(t.id, t);
        return m;
    }, new Map());

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

Note: All the above codes have been actually run and passed, and the running environment is Node v8.1.2

某草草
var result = arr.filter(function(val, index) {
    /**
     * 使用arr.slice(index + 1)获取从当前索引下一个元素到数组最后一个元素组成的数组
     * 使用findIndex在当前项的后面选项中查找是否有和当前项id值相同的选项
     */
    var index = arr.slice(index + 1).findIndex(function(item) {
         return item.id === val.id;
    });
    // 如果为-1,则说明后面没有同名id了,所以这一项可以返回
    return index === -1;
});
console.log(result);

Using arrow functions simplifies as follows:

var result = arr.filter((val, index) => arr.slice(index + 1).findIndex(item => item.id === val.id) === -1);
console.log(result);
仅有的幸福

There are already many answers here, but there is no mention of Array’s built-in function reduceRight. In fact, the questioner’s requirement is to retain the last digit of the same ID, which is very convenient to implement with reduceRight.

arr.reduceRight((r,v)=>{
    if(!r[0].has(v.id)) r[0].add(v.id) && r[1].unshift(v)
    return r
},[new Set,[]])[1]

reduceRight starts looping from the end of your original array. The initial value here is an array. r[0] is used to store the Set of ids, and r[1] is used to store the result array. If there is no id in the Set, then add this id to Set and place this item at the head of the resulting array.

In the end, the topic owner’s needs were easily achieved, and the order was guaranteed.

曾经蜡笔没有小新
function uniq(arr) {
    var idArr = [],arr2 = []
    for (var i = 0, len = arr.length; i < len; i++) {
        if (arr[i].id in idArr) {
            arr2.pop()
            arr2.push(arr[i])
        } else {
            idArr.push(arr[i].id)
            arr2.push(arr[i])
        }
    }
    return arr2
}

Personally tested and effective

伊谢尔伦
arr = [ { id: 1, content: 'a' },
        { id: 2, content: 'b' },
        { id: 2, content: 'c' },
        { id: 3, content: 'd' },
        { id: 3, content: 'e' },
        { id: 3, content: 'f' },
        { id: 3, content: 'g' },
        { id: 4, content: 'h' } ]
        
tmp = []
for(k in arr){tmp[arr[k]['id']] = arr[k]['content']}

arr = []
for(k in tmp){arr.push({'id':+k, 'content':tmp[k]})}

console.log(arr)
[ { id: 1, content: 'a' },
  { id: 2, content: 'c' },
  { id: 3, content: 'g' },
  { id: 4, content: 'h' } ]
滿天的星座

let newArr = [],

    result = [],
    status = false,
    lastResult = []
for (let i = arr.length - 1; i >= 0; i--) {
    newArr.push(arr[i])
}
for (let i = 0, len = newArr.length; i < len; i++) {
    if (result.length == 0) {
        result.push(newArr[0])
    }
    for (let j = 0; j < result.length; j++) {
        if (newArr[i].id == result[j].id) {
            console.log(newArr[i])
            status = true
        }
    }
    if (!status) {

        result.push(newArr[i])
    }
    status = false

}
for (let i = result.length - 1; i >= 0; i--) {
    lastResult.push(result[i])
}
console.log(lastResult) //为去掉相同的id 然后保留各个id的最后一项
学习ing
var arr = [ ... ]; // 这个为给定的数组
var obj = {}; // 定义一个对象存储

arr.forEach(function(v) {
    obj[v.id] = v;
    // 不管如何,直接将数组赋值给obj中下标为v.id的项,这样对应的v.id的值到最后必然是同ID最后一项
});

// 下面考虑兼容性给出新语法和常规语法
// 新语法,Object.values部分浏览器版本不支持
var result = Object.values(obj);
// 常规语法,用Array.map实现Object.values的效果
var result = Object.keys(obj).map(function(id) {
    return obj[id];
});
Peter_Zhu

Please refer to it

Array.from(arr.reduce((map, el) => map.set(el.id, el), new Map()).values())
为情所困

You can refer to what I wrote on my blog. I wrote 8 methods on my blog. http://alfierichou.top/2017/0...

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!