BKJang / digging-open-source

🔍 Digging Open Source!!
2 stars 0 forks source link

removedCount, addedCount, removedMap 없이 chagedBeforeAdded를 구현할 수 없을까? (feat.성환) #5

Open BKJang opened 3 years ago

BKJang commented 3 years ago
import {IResult, IMapInteface} from '../types';
import HashMap from './Map/HashMap';
import PolyMap from './Map/PolyMap';

export function getMapInstance(
  findKeyCallback: any
): IMapInteface<any, number> {
  if (typeof Map === 'function') {
    return new Map();
  }
  if (findKeyCallback) {
    return new HashMap();
  }
  return new PolyMap();
}

export function diff<T>(
  prevList: T[],
  newList: T[],
  findKeyCallback?: (e: T, i: number, arr: T[]) => any // 왜 반환타입이 any일까?
): IResult<T> {
  const prevKeyMap: IMapInteface<any, number> = getMapInstance(findKeyCallback); // mapClass를 꼭 따로 저장해야할까?
  const newKeyMap: IMapInteface<any, number> = getMapInstance(findKeyCallback);
  const remainedKeyMap: IMapInteface<any, number> = getMapInstance(
    findKeyCallback
  );
  const defaultCallback = findKeyCallback || ((e: T) => e);
  const prevKeys = prevList.map(defaultCallback);
  const newKeys = newList.map(defaultCallback);
  const maintained: number[][] = [];
  const fixed: boolean[] = [];
  const changed: number[][] = [];
  const added: number[] = [];
  const removed: number[] = [];
  const remained: number[] = [];

  // 1. Setting prevKeyMap, newKeyMap
  prevKeys.forEach((key, index): void => {
    prevKeyMap.set(key, index);
  });

  newKeys.forEach((key, index): void => {
    newKeyMap.set(key, index);
  });

  // 2. Setting removed and removedMap
  prevKeys.forEach((key, prevListIndex): void => {
    const newListIndex = newKeyMap.get(key);

    if (typeof newListIndex === undefined) {
      removed.push(prevListIndex);
    } else {
      remainedKeyMap.set(prevListIndex, key);
      remained.push(prevListIndex);
    }
  });

  // 3. Setting maintained, changed, fixed, added, changeBeforeAdded
  newKeys.forEach((key, newListIndex): void => {
    const prevListIndex = prevKeyMap.get(key);

    if (typeof prevListIndex === undefined) {
      added.push(newListIndex);
    } else {
      maintained.push([prevListIndex, newListIndex]);
      fixed.push(prevListIndex === newListIndex);
      if (prevListIndex !== newListIndex) {
        changed.push([prevListIndex, newListIndex]);
      }
    }
  });

  const remainedKeyList = remained.map(item => {
    return remainedKeyMap.get(item);
  });

  const maintainedKeyList = maintained.map(item => {
    return prevKeys[item[0]];
  });

  const changedBeforeAdded = maintainedKeyList.map(item => {
    return [remainedKeyList.indexOf(item), maintainedKeyList.indexOf(item)];
  });

  removed.reverse(); 
  return {
    prevList,
    newList,
    added,
    removed,
    changed,
    maintained,
    changedBeforeAdded,
  };
}
BKJang commented 3 years ago

typeof 쓰는 이유

왜 removed를 reverse해줄까?