All files / findListDuplicatesByKeyList findListDuplicatesByKeyList.ts

100% Statements 14/14
100% Branches 2/2
100% Functions 3/3
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 611x                                                                             1x       7x 7x   7x 43x 22x   22x 6x 6x   16x       7x    
import { get } from '../get/get';
 
/**
 * @description 查找列表中指定键值重复的项
 * @function findListDuplicatesByKeyList
 * @param {Array<T>} data - 数据列表
 * @param {Array<string>} keyList - 用于比较的键列表,支持路径写法 ['a.b.c', 'd']
 * @returns {Array<T>} 返回重复项
 * @template T
 * @author liukun <919590347@qq.com>
 * @example
 * import { findListDuplicatesByKeyList } from '@wont/utils'
 *
 * const data = [
 *   { id: 1, name: 'Alice', age: 25 },
 *   { id: 3, name: 'Alice', age: 25 },
 *   { id: 4, name: 'Charlie', age: 35 },
 *   { id: 5, name: 'Alice', age: 25 },
 * ];
 * const expectedData = [
 *   { id: 1, name: 'Alice', age: 25 },
 *   { id: 3, name: 'Alice', age: 25 },
 *   { id: 5, name: 'Alice', age: 25 },
 * ];
 * findListDuplicatesByKeyList(data, ['name', 'age'])  // returns expectedData
 *
 * const data1 = [
 *     { id: 1, name: 'Alice', details: { age: 25, city: 'New York' } },
 *     { id: 2, name: 'Bob', details: { age: 30, city: 'Chicago' } },
 *     { id: 3, name: 'Alice', details: { age: 25, city: 'New York' } },
 *     { id: 4, name: 'Charlie', details: { age: 35, city: 'San Francisco' } },
 *   ];
 * const expectedData1 = [
 *   { id: 1, name: 'Alice', details: { age: 25, city: 'New York' } },
 *   { id: 3, name: 'Alice', details: { age: 25, city: 'New York' } },
 * ];
 * findListDuplicatesByKeyList(data1, ['name', 'details.age']); // returns expectedData1
 */
 
export const findListDuplicatesByKeyList = <T extends Record<string, unknown>>(
  data: T[],
  keyList: (keyof T | string)[],
): T[] => {
  const seen = new Map<string, T>();
  const duplicates: T[] = [];
 
  data.forEach((item) => {
    const key = keyList.map((k) => get(item, k as string)).join('_');
    const existing = seen.get(key);
 
    if (existing) {
      duplicates.push(item);
      duplicates.push(existing);
    } else {
      seen.set(key, item);
    }
  });
 
  return Array.from(new Set(duplicates));
};