type AsCamelCase<S extends string> = S extends `${infer A}_${infer B}` ? `${A}${Capitalize<AsCamelCase<B>>}` : S;
type CamelCaseKeysRecord<T> = T extends Record<PropertyKey, unknown> ? {
[K in string & keyof T as AsCamelCase<K>]: CamelCaseKeysRecord<T[K]>;
} & {
[K in Exclude<keyof T, string>]: CamelCaseKeysRecord<T[K]>;
} : T;
function toCamelCaseKeys<T>(val: T): CamelCaseKeysRecord<T> {
if (Array.isArray(val)) {
return val.map(toCamelCaseKeys) as unknown as CamelCaseKeysRecord<T>;
}
if (typeof val === 'object') {
return Object.fromEntries(Object
.entries(val)
.map(([k, v]) => [
k.replace(/_+(.)/g, (_, g) => g.toUpperCase()),
toCamelCaseKeys(v as Record<string, unknown>),
])) as CamelCaseKeysRecord<T>;
}
return val as unknown as CamelCaseKeysRecord<T>;
}
function parsePath(path) {
return path.split(',').reduce((acc, item) => {
const [key, value] = item.split('=');
switch(key) {
case 'name':
acc.name = value;
break;
case 'f':
case 'g':
acc[key].push(value);
break;
}
return acc;
}, {
name: '',
f: [],
g: []
});
}
function normalizeTree(tree) {
return Object.keys(tree).map(label => {
const item = tree[label];
if(item.id) { return item; }
const children = normalizeTree(item);
const id = `[${children.map(({id}) => id).join(',')}]`;
return {id, label, children};
});
}
function reduceToTree(data) {
return normalizeTree(data.reduce((acc, {path, id}) => {
const {name, f, g} = parsePath(path);
const target = f.reverse().concat(name).reduce((target, label) => {
return target[label] || (target[label] = {});
}, acc);
target.id = id;
target.label = name;
target.g = g;
return acc;
}, {}));
}
console.log(reduceToTree([
{
"path": "name=Tel6,g=tovarov,g=catalog",
"id": "6000",
"name": "Tel6"
},
{
"path": "name=Tel1,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
"id": "1000",
"name": "Tel1"
},
{
"path": "name=Tel2,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
"id": "2000",
"name": "Tel2"
},
{
"path": "name=Tel3,f=Galaxy,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
"id": "3000",
"name": "Tel3"
},
{
"path": "name=Tel4,f=A,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
"id": "4000",
"name": "Tel4"
},
{
"path": "name=Tel5,f=A,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
"id": "5000",
"name": "Tel5"
}
// ...
]));
function recursiveRequest(requestData) {
return fetch(
//здесь формируем запрос из requestData
).then(response => response.json()).then(result => {
if(result.isFinal) return result; // тут условие
return recursiveRequest(result.nextRequest); //вызываем следующий запрос
});
}
recursiveRequest({}).then(finalResult => {
//работаем с последним результатом
});
const curring = (...initArgs) => {
let sum = 0;
const curried = (...args) => {
sum = args.reduce((a, b) => a + b, sum);
return curried;
};
curried.valueOf = () => sum;
return curried(...initArgs);
};
в текущей области видимости 'func' не объявлена
var f = function func() {
console.log(func.name); // 'func'
};
console.log(f.name); // 'func'
console.log(func.name); // Reference error так как func нет в этой области видимости