【问题标题】:Why can't I produce unique objects array in this snippet?为什么我不能在这个片段中生成唯一的对象数组?
【发布时间】:2018-03-01 16:27:39
【问题描述】:

我有以下代码 sn-p,我希望在其中过滤原始数组(过滤器)并获得唯一的过滤器数组。

我想我尝试了所有可能的方法,它(uniqueFilters 数组)仍然是相同的 11 成员原始数组。

怎么了?

我怎样才能确保这个数组实际上被过滤到只有几个独特的元素? (他们都来自同一个地方,都是一样的)

更新: - 答案成功解决了js代码中的问题。 - 在实际的应用程序中,我还必须处理打字稿才能使用建议的答案。所以也许会帮助某人:

let newUniqueFilters = Array.from(new Map(filters.map(f => [f._id, f] as [string, any])).values());

var filters = [{
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}]

// first method:
var uniqueFilters = [];
for(let i = 0; i < filters.length; i++) {
    if(uniqueFilters.indexOf(filters[i]) == -1){
        uniqueFilters.push(filters[i])
    }
}
console.log("first method")
console.log("original array length:" + filters.length)
console.log("unique array length:" + uniqueFilters.length)

// second method:
//var uniqueFilters = filters.filter(function(elem, index, self) {
//        return index == self.indexOf(elem);
//});
//console.log("second method")
//console.log("original array length:" + filters.length)
//console.log("unique array length:" + uniqueFilters.length)

// suggested method 1:
var newUniqueFilters = Array.from(new Map(filters.map(f => [f._id, f])).values());
console.log(newUniqueFilters)

【问题讨论】:

  • 对象比较不是基于对象内容,而是基于身份。一个对象总是!== 每隔一个对象。
  • 那么我不能这样解决我的问题吗?哎哟

标签: javascript arrays set unique


【解决方案1】:

您可以使用Map

filters = Array.from(new Map(filters.map(f => [f._id, f])).values());

这假定比较 _id 值就足够了,它们唯一地标识过滤器。

请注意,比较对象本身(使用indexOf 或类似方法)将永远不会显示重复,因为所有对象都是不同的引用(副本),即使它们看起来相同。一般来说{} === {} 总是假的。

【讨论】:

  • 不错的解决方案。但是将它传递给 Map 类的新实例有什么好处吗?为什么不干脆做:filters = filters.map(f =&gt; [f._id, f]); 是为了便于阅读吗?
  • @AlexanderEdwards,new Map( ) 将折叠具有相同 id 的项目(即在对中具有相同的第一个值),而单独的 .map() 不会减少您进入的项目数量你的结果。
  • 嘿哟,这行得通,但更重要的是我要感谢你对对象比较的解释,现在我知道我的错误在哪里了哈哈。
  • 在涉及到对象时感觉就像是 - 最佳实践是识别这些对象,然后将其用作 copmparison 的基础。
  • 确实是这样。
【解决方案2】:

它不起作用,因为过滤器数组中的每个元素都有不同的内存位置,并且对象通过内存位置进行比较。

所以每次你比较uniqueFilters中过滤器数组的对象存在时,它根本不存在,因为每个对象都有不同的内存位置。 因此它将推送 uniqueFilters 中的每个元素。

【讨论】:

    【解决方案3】:

    尝试更改此行

    if(uniqueFilters.indexOf(filters[i]) == -1){ 到 if(uniqueFilters.indexOf(filters[i]) === -1){

    如果不工作,您也可以尝试将特定属性与所有 uniqueFilter 进行比较

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-13
      • 1970-01-01
      • 2018-05-08
      • 2021-02-12
      相关资源
      最近更新 更多