Skip to content

Instantly share code, notes, and snippets.

@umezo
Last active February 7, 2018 08:27
Show Gist options
  • Save umezo/8b4405decaeec963317c03e302cac959 to your computer and use it in GitHub Desktop.
Save umezo/8b4405decaeec963317c03e302cac959 to your computer and use it in GitHub Desktop.
type Query = string | number | (any) => boolean;
type Collection<T> = Array<T> | {[key: string]: Collection<T>};
type Mapper<T> = (T) => T;
function update<T: Collection<any>>(collection: T, queryList: Query[], mapper: Mapper<any>): T {
const rootCollection = Array.isArray(collection) ? collection.slice() : _assign({}, collection);
if (queryList.length === 0) {
return mapper(rootCollection);
} else {
const query = queryList[0];
let updateTarget;
if (Array.isArray(rootCollection)) {
let index: number = -1;
if (typeof query === 'number') {
updateTarget = rootCollection[query];
index = query;
} else if (typeof query === 'function') {
updateTarget = _find(rootCollection, query);
index = rootCollection.indexOf(updateTarget);
} else {
console.log(rootCollection, query); // eslint-disable-line no-console, ここは開発中に潰しきるべき箇所で、デバッグがめんどくさいところなので親切ログを出す
throw new Error(`query type must be number or function for Array. '${typeof query}' was given`);
}
if (!updateTarget) {
throw new Error(`target not found with '${query.toString()}'`);
}
rootCollection[index] = update(updateTarget, queryList.slice(1), mapper);
} else {
const key = query.toString();
if (typeof query === 'string' || typeof query === 'number') {
updateTarget = rootCollection[key];
console.log(rootCollection, query); // eslint-disable-line no-console, ここは開発中に潰しきるべき箇所で、デバッグがめんどくさいところなので親切ログを出す
throw new Error(`query type must be string or number for Obect. '${typeof query}' was given`);
}
if (!updateTarget) {
throw new Error(`target not found with '${query.toString()}'`);
}
rootCollection[key] = update(updateTarget, queryList.slice(1), mapper);
}
return rootCollection;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment