export function mapValuesDeep<T>(
  obj: any,
  isItem: (v: any) => boolean,
  handle: (v: any) => T
) {
  const arr: T[] = [];
  function mapItem(obj: any) {
    if (isItem(obj)) {
      arr.push(handle(obj));
    } else if (obj instanceof Array) {
      obj.forEach(mapItem);
    } else if (obj instanceof Object) {
      Object.values(obj).forEach(mapItem);
    }
  }
  mapItem(obj);
  return arr;
}

export function eachValuesAndPathsDeep(
  obj: any,
  isItem: (v: any) => boolean,
  itemHandle: (v: any, paths: string[]) => void,
  paths: string[] = []
) {
  if (isItem(obj)) {
    itemHandle(obj, paths);
  } else if (obj instanceof Array) {
    obj.forEach((item, i) =>
    eachValuesAndPathsDeep(item, isItem, itemHandle, [...paths, i.toString()])
    );
  } else if (obj instanceof Object) {
    Object.entries(obj).map(([key, item]) => {
      eachValuesAndPathsDeep(item, isItem, itemHandle, [...paths, key]);
    });
  }
}
