Source code

function filterRepeat(sourceData) {
	if(! sourceData ||Object.prototype.toString.call(sourceData) ! = ='[object Array]')
		throw new Error('Parameter sourceData must be an array');
	else if (sourceData.length === 0) return sourceData;

	let entriesData = [];
	let repeatIndexes = [];

	entriesData = generatorEntriesData(sourceData);
	repeatIndexes = getRepeatIndexes(entriesData);

	console.log('----- duplicate item index -----');
	console.log(repeatIndexes, '\n');

	return filter(sourceData, repeatIndexes);
}

function generatorEntriesData(sourceData) {
	let sourceCacheData = [];
	let dataType = ' ';
	let result = null;

	for (let data of sourceData) {
		dataType = Object.prototype.toString.call(data);

		if (dataType === '[object Array]') {
			result = generatorEntriesData(data);
		} else if (dataType === '[object Object]') {
			result = generatorEntriesData(Object.entries(data));
		} else if (dataType === '[object Function]') {
			result = data.toLocaleString();
		} else {
			result = data;
		}

		sourceCacheData.push(result);
	}

	return sourceCacheData;
}

function getRepeatIndexes(entries) {
	let indexes = new Set(a);let indexesLen = 0;
	let arrIndexes = []; // Record the index of array entries
	let entriesCache = new Set(a);let isEquals = true;

	for (let i = 0; i < entries.length; i++) {
		if (Object.prototype.toString.call(entries[i]) === '[object Array]') {
			indexesLen = indexes.size;

			for (let index of arrIndexes) {
				isEquals = isEqualsFn(entries[index], entries[i]);

				if (isEquals) {
					indexes.add(i);
					break;
				} else {
					isEquals = true; }}if(indexes.size === indexesLen) { arrIndexes.push(i); }}else if (entriesCache.has(entries[i])) {
			indexes.add(i);
		} else{ entriesCache.add(entries[i]); }}return indexes;
}

function isEqualsFn(p1, p2) {
	const p1Type = Object.prototype.toString.call(p1);
	const p2Type = Object.prototype.toString.call(p2);
	let isEquals = true;

	if (p1Type === p2Type) {
		if (p1Type === '[object Array]') {
			if (p1.length === p2.length) {
				for (let i = 0; i < p1.length; i++) {
					isEquals = isEqualsFn(p1[i], p2[i]);
					if(! isEquals)break; }}else {
				 isEquals = false; }}else if (p1Type === '[object Object]') {
			isEquals = isEqualsFn(Object.entries(p1).sort(), Object.entries(p2).sort());
		} else if (p1Type === '[object Function]') {
			isEquals = p1Type.name === p2Type.name &&
				p1Type.toLocaleString().length === p2Type.toLocaleString().length;
		} else{ isEquals = p1 === p2; }}else {
		isEquals = false;
	}

	return isEquals;
}

function filter(sourceData, repeatIndexes) {
	let result = [];

	sourceData.forEach((item, index) = > {
		if(! repeatIndexes.has(index)) result.push(item); });return result;
}

/***** rua~ *****/
let sourceData = [
	1.1.'2'.'2'.null.null.undefined.undefined[1.2],
	[1.2],
	[{ id: 1 }, { id: 2 }],
	[{ id: 1 }, { id: 2}, {id: 1.name: 'Tom'
	},
	{
		id: 1,
		sayHello() {}
	},
	{
		id: 1,
		sayHello() {}
	},
	{
		id: 1,
		sayHello() { return 'Hello'; }}, {id: 1,
		sayHello() { return 'Hello'; }}, {id: 2,
		sayHello() { return 'Hello'; }}];console.log('----- before heavy -----');
console.log(sourceData, '\n');

const filteredData = filterRepeat(sourceData);

console.log('----- after heavy -----');
console.log(filteredData);
Copy the code

Test case

Result