cari

Rumah  >  Soal Jawab  >  teks badan

javascript - Masalah deduplikasi tatasusunan

Andaikan sekarang terdapat pelbagai objek

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'
    },
]

Saya ingin mengalih keluar id yang sama dan menyimpan item terakhir setiap id

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

Adakah cara yang lebih baik? .

女神的闺蜜爱上我女神的闺蜜爱上我2791 hari yang lalu699

membalas semua(9)saya akan balas

  • 漂亮男人

    漂亮男人2017-06-28 09:26:12

    Mengikut konvensyen, kod ES6

    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;
    }, []);

    Ada masalah di sini, findIndex Sekurang-kurangnya dua pelayar tidak menyokongnya, jadi jika ia tidak menyokongnya, anda perlu menulis satu sendiri

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

    Penyelesaian lain

    Penyelesaian klasik, gunakan Map

    Oleh kerana id bukan rentetan, kelas ES6 Map digunakan. Apabila jumlah data adalah besar, menggunakan jadual carian boleh meningkatkan kecekapan dengan ketara berbanding carian linear dalam senarai.

    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;

    Malah, anda juga boleh menggunakan objek sebagai ganti peta, sekurang-kurangnya dalam use case ini tidak akan ada masalah. Kerana tiada ciri es6, kami hanya menggunakan sintaks es5. Struktur kod dan logik adalah sama seperti perenggan di atas

    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;

    Penyelesaian pelik, menggunakan id integer

    Oleh kerana ia adalah id integer, anda boleh terus memasukkannya ke dalam array mengikut id ini. Jika ID yang sama ditemui, ia akan diganti terus. Jika id tidak berturut-turut, anda perlu menapis elemen kosong di hujung

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

    Terdapat masalah lain dengan penyelesaian ini Ia tidak dapat mengekalkan susunan unsur tatasusunan asal. Kemudian seseorang pasti akan berfikir bahawa penyelesaian menggunakan Map juga boleh mengurangkan kod menjadi kod yang sama tanpa menjadikannya begitu rumit Sudah tentu, ia juga mungkin kehilangan susunan asal

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

    Nota: Semua kod di atas sebenarnya telah dijalankan dan diluluskan, dan persekitaran berjalan ialah Node v8.1.2

    balas
    0
  • 某草草

    某草草2017-06-28 09:26:12

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

    Menggunakan fungsi anak panah memudahkan seperti berikut:

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

    balas
    0
  • 仅有的幸福

    仅有的幸福2017-06-28 09:26:12

    Terdapat banyak jawapan di sini, tetapi tidak ada menyebut tentang fungsi terbina dalam Array reduceRight Malah, keperluan penyoal adalah untuk mengekalkan digit terakhir ID yang sama, yang sangat mudah untuk dilaksanakan menggunakan 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 mula menggelung dari hujung tatasusunan asal anda Nilai awal di sini ialah tatasusunan r[0] digunakan untuk menyimpan Set id, dan r[1] menyimpan tatasusunan hasil Tetapkan, kemudian tambah id ini pada Tetapkan dan letakkan item ini di kepala tatasusunan yang terhasil.

    Akhirnya, keperluan pemilik topik dapat dicapai dengan mudah, dan pesanan itu dijamin.

    balas
    0
  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-06-28 09:26:12

    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
    }

    Diuji secara peribadi dan berkesan

    balas
    0
  • 伊谢尔伦

    伊谢尔伦2017-06-28 09:26:12

    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' } ]

    balas
    0
  • 滿天的星座

    滿天的星座2017-06-28 09:26:12

    biar 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的最后一项

    balas
    0
  • 学习ing

    学习ing2017-06-28 09:26:12

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

    balas
    0
  • 天蓬老师

    天蓬老师2017-06-28 09:26:12

    Sila rujuk

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

    balas
    0
  • 为情所困

    为情所困2017-06-28 09:26:12

    Boleh rujuk apa yang saya tulis di blog saya, saya tulis 8 kaedah di blog saya. http://alfierichou.top/2017/0...

    balas
    0
  • Batalbalas