Skip to content
← Back to Snippets
Code

Duplicate Record Cluster Finder

Finds duplicate record clusters by normalizing selected identity fields into stable comparison keys.

Purpose

Finds duplicate record clusters by normalizing selected identity fields into stable comparison keys.

Snippet details

ContextArrayLevelAdvancedCopy-and-paste statusMarked safe after review.

Categories

  • Security

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Duplicate Record Cluster Finder.
 *
 * Purpose:
 * Groups records that share the same normalized identity fields so duplicate
 * candidates can be reviewed before any merge or delete action occurs.
 *
 * @param array $records Records to cluster.
 * @param array $identity_fields Field names used to identify duplicates.
 * @return array Duplicate clusters keyed by normalized identity.
 */
function ogSnippetDuplicateRecordClusterFinder(array $records, array $identity_fields): array {
	$buckets = array();
	$clusters = array();

	foreach ($records as $index => $record) {
		if (is_array($record) === false) {
			continue;
		}

		$key_parts = array();

		foreach ($identity_fields as $field_name) {
			$value = '';
			$clean_field = (string) $field_name;

			if ($clean_field !== '' && isset($record[$clean_field]) === true) {
				$value = strtolower(trim((string) $record[$clean_field]));
				$value = preg_replace('/\s+/', ' ', $value);
			}

			$key_parts[] = $clean_field.'='.$value;
		}

		$bucket_key = implode('|', $key_parts);

		if (isset($buckets[$bucket_key]) === false) {
			$buckets[$bucket_key] = array();
		}

		$buckets[$bucket_key][] = array(
			'index' => (int) $index,
			'record' => $record
		);
	}

	foreach ($buckets as $bucket_key => $bucket_records) {
		if (count($bucket_records) > 1) {
			$clusters[$bucket_key] = $bucket_records;
		}
	}

	return $clusters;
}

$records = array(
	array('call_sign' => 'Red Five', 'pilot' => 'Luke Skywalker'),
	array('call_sign' => ' red   five ', 'pilot' => 'Luke Skywalker'),
	array('call_sign' => 'Gold Leader', 'pilot' => 'Jon Vander')
);
$clusters = ogSnippetDuplicateRecordClusterFinder($records, array('call_sign', 'pilot'));

echo 'Star Wars duplicate record clusters: '.count($clusters);