代码有效(大部分)。但未能删除重复项

Code works (mostly). But failure to remove duplicates

总结:

嘿,我有一些数据的过滤器。它过滤得很好,但没有删除重复的对象。参数顺序:

1。数据源
2。过滤器(删除所有匹配项)
3。 unique:(是否去除重复项)
4。 prop(对象属性 - 用于列出未过滤项目的属性 - 未使用))

数据:

var moduleData = [
     {manufacturer: "SunPower Corp.", productNo: "SPR-M475-COM-MLSD", watts: 475, cells: 72, warranty: 25, degradation: 0, volume: 0, smartModule: false, adder: 0, available: true},
     {manufacturer: "TestCo", productNo: "TE-STc001", watts: 475, cells: 72, warranty: 25, degredation: 0, volume: 0, smartModule: false, adder: 0, available: true},
     {manufacturer: "TestCo", productNo: "TE-STc001", watts: 475, cells: 72, warranty: 25, degredation: 0, volume: 0, smartModule: false, adder: 0, available: true},
     {manufacturer: "TestCo", productNo: "TE-STc002", watts: 475, cells: 72, warranty: 25, degredation: 0, volume: 0, smartModule: false, adder: 0, available: true},
     {manufacturer: "TestCo", productNo: "TE-STc002.5", watts: 475, cells: 72, warranty: 25, degredation: 0, volume: 0, smartModule: false, adder: 0, available: true},
     {manufacturer: "TestCoDuplicate", productNo: "TE-STc002.5", watts: 430, cells: 71, warranty: 23, degredation: 2, volume: 1, smartModule: true, adder: 5, available: true},
     {manufacturer: "TestCo", productNo: "TE-STc003", watts: 475, cells: 72, warranty: 25, degredation: 0, volume: 0, smartModule: false, adder: 0, available: true},
    ]

函数:

const filters = {}

const getFilteredArray = ((data, filters, isItUnique, prop  ) => {
//Arrays

    // filtered Array =======================================
    if ((prop.length > 0 || prop != undefined || prop != null) && (prop.length == 0 || prop == undefined || prop == null)){ 
        let nonUniqueArray = data.filter(p => 
            filters.every(f=> Object.keys(f).every(k => p[k] === f[k]))
        )
        console.log('filtered Array - (unique, no prop) ')
        
        var unique = []
        //XXXXXXXXXXXXX make array unique XXXXXXXXXXXXXXXXX
        
            const uniqueArray = nonUniqueArray.filter(element => {
                const isDuplicate = unique.includes(element);

                if (!isDuplicate) {
                    unique.push(element)
            
                    return true
                }
            })

        return uniqueArray
    }
})


filters.available = true
filters.manufacturer = "TestCo"


//console.log(filters)
console.log(getFilteredArray(moduleData, [filters], "unique", "" ))

所以我正在寻找 TestCo 制造商的产品,该产品可用并希望删除重复项。


返回:

Console:[Object, Object, Object, Object, Object] (5)<br>
0 {manufacturer: "TestCo", productNo: "TE-STc001", watts: 475, cells: 72, warranty: 25, …}<br>
1 {manufacturer: "TestCo", productNo: "TE-STc001", watts: 475, cells: 72, warranty: 25, …}<br>
2 {manufacturer: "TestCo", productNo: "TE-STc002", watts: 475, cells: 72, warranty: 25, …}<br>
3 {manufacturer: "TestCo", productNo: "TE-STc002.5", watts: 475, cells: 72, warranty: 25, …}<br>
4 {manufacturer: "TestCo", productNo: "TE-STc003", watts: 475, cells: 72, warranty: 25, …}<br>

很明显,您可以看到产品编号 TE-STc001 两次。 (未删除)。作为一个完整的副本,我认为其中一个不会添加到 uniqueArray。为什么会这样,我该如何修复我的代码?提前致谢!

所以,我找到了解决方案:

将对象字符串化然后比较似乎有所不同。我听取了jFriend00的建议,在过滤之前先删除重复项。

解决方法:

// filtered Array =======================================
    if ((prop.length > 0 || prop != undefined || prop != null) && (prop.length == 0 || prop == undefined || prop == null)){ 
        console.log('filtered Array - (unique, no prop) ')
        
        //Make data unique
        const uniqueArray = data.filter((object,index) => index === data.findIndex(obj => JSON.stringify(obj) === JSON.stringify(object)));
            
        return uniqueArray
    }

... 这使得提供过滤列表也变得不那么困难。 (对于下拉菜单。)

// filtered List =======================================
    if ((prop.length > 0 || prop != undefined || prop != null) && (prop.length !== 0 || prop.length !== undefined || prop.length !== null)){ 
        console.log('filtered List - (unique, prop) ')

        //Make data unique
        const uniqueArray = data.filter((object,index) => index === data.findIndex(obj => JSON.stringify(obj) === JSON.stringify(object)));

        //filter the list for matches
        let UniqueArray = uniqueArray.filter(p => 
            filters.every(f=> Object.keys(f).every(k => p[k] === f[k]))
        )

        //map Array into the desired list
        let uniquePropList = UniqueArray.map(item => item[prop])

        //look again for duplicates within the list
        var unique = []
        let doubleUniquePropList = uniquePropList.filter(element => {
            const isDuplicate = unique.includes(element);

            if (!isDuplicate) {
                unique.push(element)
        
                return true
            }
        })

        return doubleUniquePropList
    }

现在我可以将此功能用于许多不同的用例!谢谢你们的帮助!我希望这可以帮助其他人!

根据您的用例,您可以通过多种方式从数组中删除重复对象。

1.) 按一个对象过滤重复项属性

const uniqueData = moduleData.filter((v,i,a) => a.findIndex(v2 => (v2.productNo === v.productNo)) === i)

2.) 按多个属性筛选

const uniqueData = moduleData.filter((v,i,a) => a.findIndex(v2 => ['productNo','manufacturer'].every(k => v2[k] === v[k])) === i)

3.) 检查所有属性并过滤重复项(如果您知道数据的质量,这可能有点矫枉过正)

const uniqueData = moduleData.filter((v,i,a) => a.findIndex(v2 => [...Object.keys(moduleData[0])].every(k => v2[k] === v[k])) === i)

在您的解决方案的后半部分,您无需在按照原样为下拉列表值创建对象属性数组后再次查找列表中的重复项,只需使用 Set constructor and the spread语法

doubleUniquePropList = [...new Set(uniquePropList)]