Creating nested objects from string
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
I implemented a method, to create an object based on a series of strings that are passed to it, of any depth or length. The way I implemented the solution was to map over the arguments. Assuming that strings are passed in the form x.a
, it then splits the string by the '.', returning just a single object with that key if the array only had one element otherwise, it was passed through a reducer to produce an array of objects which would then be merged into one object.
I'd like to make this better/ are there any concerns with using a reducer in a map function, since it's on the order of O(n2)?
type TKeys = string
type TTarget =
[key: string]: TTarget
type TTemplate =
target: TTarget,
props: ReadonlyArray<string>
interface ITemplate
target: TTemplate["target"]
,
props: ReadonlyArray<string>
const createObject = <T>(...keys: TKeys): T => (
keys.map(key =>
const props = key.split('.');
const reducerTemplate: ITemplate =
target: ,
props: ['']
return props.length < 2
?
[key]: ''
: props.reduce((obj: ITemplate, prop: string) =>
const target: ITemplate["target"] = obj.target
if (obj.props.length === 0)
console.log(obj, prop);
obj.props = [prop];
target[prop] = ;
return obj;
const object: ITemplate["target"] = obj
.props
.reduce((prev: TTemplate["target"] , next: string) => (target[next] , reducerTemplate)
).reduce((main: | TTarget, obj: TTarget ): TTarget => (
...main,
...obj
), ))
Example Usage:
createObject('a.b.c.d', 'hello.world', 'test')
//outputs
a:
b:
c:
d: '',
,
,
,
hello:
world: '',
,
test: '',
createObject('hello')
//outputs
hello: ''
createObject('a.b')
//outputs
a:
b: '',
,
;
javascript object-oriented ecmascript-6 typescript
add a comment |Â
up vote
3
down vote
favorite
I implemented a method, to create an object based on a series of strings that are passed to it, of any depth or length. The way I implemented the solution was to map over the arguments. Assuming that strings are passed in the form x.a
, it then splits the string by the '.', returning just a single object with that key if the array only had one element otherwise, it was passed through a reducer to produce an array of objects which would then be merged into one object.
I'd like to make this better/ are there any concerns with using a reducer in a map function, since it's on the order of O(n2)?
type TKeys = string
type TTarget =
[key: string]: TTarget
type TTemplate =
target: TTarget,
props: ReadonlyArray<string>
interface ITemplate
target: TTemplate["target"]
,
props: ReadonlyArray<string>
const createObject = <T>(...keys: TKeys): T => (
keys.map(key =>
const props = key.split('.');
const reducerTemplate: ITemplate =
target: ,
props: ['']
return props.length < 2
?
[key]: ''
: props.reduce((obj: ITemplate, prop: string) =>
const target: ITemplate["target"] = obj.target
if (obj.props.length === 0)
console.log(obj, prop);
obj.props = [prop];
target[prop] = ;
return obj;
const object: ITemplate["target"] = obj
.props
.reduce((prev: TTemplate["target"] , next: string) => (target[next] , reducerTemplate)
).reduce((main: | TTarget, obj: TTarget ): TTarget => (
...main,
...obj
), ))
Example Usage:
createObject('a.b.c.d', 'hello.world', 'test')
//outputs
a:
b:
c:
d: '',
,
,
,
hello:
world: '',
,
test: '',
createObject('hello')
//outputs
hello: ''
createObject('a.b')
//outputs
a:
b: '',
,
;
javascript object-oriented ecmascript-6 typescript
Can you post some example input and output? It would make it a lot easier to understand.
â Máté Safranka
Jun 4 at 22:11
Typescript chokes on this as soon as I paste it into any playground I'm familiar with, even ignoring the compiler errors, the code itself doesn't seem to work.Cannot set property 'a' of undefined
given your first example.
â Gerrit0
Jun 6 at 1:25
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I implemented a method, to create an object based on a series of strings that are passed to it, of any depth or length. The way I implemented the solution was to map over the arguments. Assuming that strings are passed in the form x.a
, it then splits the string by the '.', returning just a single object with that key if the array only had one element otherwise, it was passed through a reducer to produce an array of objects which would then be merged into one object.
I'd like to make this better/ are there any concerns with using a reducer in a map function, since it's on the order of O(n2)?
type TKeys = string
type TTarget =
[key: string]: TTarget
type TTemplate =
target: TTarget,
props: ReadonlyArray<string>
interface ITemplate
target: TTemplate["target"]
,
props: ReadonlyArray<string>
const createObject = <T>(...keys: TKeys): T => (
keys.map(key =>
const props = key.split('.');
const reducerTemplate: ITemplate =
target: ,
props: ['']
return props.length < 2
?
[key]: ''
: props.reduce((obj: ITemplate, prop: string) =>
const target: ITemplate["target"] = obj.target
if (obj.props.length === 0)
console.log(obj, prop);
obj.props = [prop];
target[prop] = ;
return obj;
const object: ITemplate["target"] = obj
.props
.reduce((prev: TTemplate["target"] , next: string) => (target[next] , reducerTemplate)
).reduce((main: | TTarget, obj: TTarget ): TTarget => (
...main,
...obj
), ))
Example Usage:
createObject('a.b.c.d', 'hello.world', 'test')
//outputs
a:
b:
c:
d: '',
,
,
,
hello:
world: '',
,
test: '',
createObject('hello')
//outputs
hello: ''
createObject('a.b')
//outputs
a:
b: '',
,
;
javascript object-oriented ecmascript-6 typescript
I implemented a method, to create an object based on a series of strings that are passed to it, of any depth or length. The way I implemented the solution was to map over the arguments. Assuming that strings are passed in the form x.a
, it then splits the string by the '.', returning just a single object with that key if the array only had one element otherwise, it was passed through a reducer to produce an array of objects which would then be merged into one object.
I'd like to make this better/ are there any concerns with using a reducer in a map function, since it's on the order of O(n2)?
type TKeys = string
type TTarget =
[key: string]: TTarget
type TTemplate =
target: TTarget,
props: ReadonlyArray<string>
interface ITemplate
target: TTemplate["target"]
,
props: ReadonlyArray<string>
const createObject = <T>(...keys: TKeys): T => (
keys.map(key =>
const props = key.split('.');
const reducerTemplate: ITemplate =
target: ,
props: ['']
return props.length < 2
?
[key]: ''
: props.reduce((obj: ITemplate, prop: string) =>
const target: ITemplate["target"] = obj.target
if (obj.props.length === 0)
console.log(obj, prop);
obj.props = [prop];
target[prop] = ;
return obj;
const object: ITemplate["target"] = obj
.props
.reduce((prev: TTemplate["target"] , next: string) => (target[next] , reducerTemplate)
).reduce((main: | TTarget, obj: TTarget ): TTarget => (
...main,
...obj
), ))
Example Usage:
createObject('a.b.c.d', 'hello.world', 'test')
//outputs
a:
b:
c:
d: '',
,
,
,
hello:
world: '',
,
test: '',
createObject('hello')
//outputs
hello: ''
createObject('a.b')
//outputs
a:
b: '',
,
;
javascript object-oriented ecmascript-6 typescript
edited Jun 4 at 23:53
asked Jun 4 at 19:58
user3655510
162
162
Can you post some example input and output? It would make it a lot easier to understand.
â Máté Safranka
Jun 4 at 22:11
Typescript chokes on this as soon as I paste it into any playground I'm familiar with, even ignoring the compiler errors, the code itself doesn't seem to work.Cannot set property 'a' of undefined
given your first example.
â Gerrit0
Jun 6 at 1:25
add a comment |Â
Can you post some example input and output? It would make it a lot easier to understand.
â Máté Safranka
Jun 4 at 22:11
Typescript chokes on this as soon as I paste it into any playground I'm familiar with, even ignoring the compiler errors, the code itself doesn't seem to work.Cannot set property 'a' of undefined
given your first example.
â Gerrit0
Jun 6 at 1:25
Can you post some example input and output? It would make it a lot easier to understand.
â Máté Safranka
Jun 4 at 22:11
Can you post some example input and output? It would make it a lot easier to understand.
â Máté Safranka
Jun 4 at 22:11
Typescript chokes on this as soon as I paste it into any playground I'm familiar with, even ignoring the compiler errors, the code itself doesn't seem to work.
Cannot set property 'a' of undefined
given your first example.â Gerrit0
Jun 6 at 1:25
Typescript chokes on this as soon as I paste it into any playground I'm familiar with, even ignoring the compiler errors, the code itself doesn't seem to work.
Cannot set property 'a' of undefined
given your first example.â Gerrit0
Jun 6 at 1:25
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
0
down vote
I think a plain loop works better here. I don't know TypeScript unfortunately, but I'm pretty sure you can adapt this easily enough:
function createObject(...keys)
let obj = ;
for (let key of keys)
let putInto = obj;
let tokens = key.split('.');
for (let i = 0; i < tokens.length; i++) value;
putInto = putInto[name];
return obj;
add a comment |Â
up vote
0
down vote
In general case this always maps to O(n2). You may introduce some complex optimisations but this yields to long hardly readable code. Are you sure you will benefit from this?
I am a huge fan of CoffeeScript language and both CoffeeScript and TypeScript do a lot of hidden work so it is crucial to see the compiled JavaScript. Also, if your primary concearn is perfomance you will benefit greatly from plain JavaScript solution.
So here is my attempt on it. It is simular to Máté Safranka solution (which is quite nice and readable). It uses Array.prototype.reduce
to remove all local variables in favor of function arguments:
function createObject(...pathes)
return pathes.reduce(function (obj, path)
path.split('.').reduce((obj, key) => obj[key] = obj[key] , );
// Some tests
console.log(createObject('a.b.c.d', 'hello.world', 'test'));
console.log(createObject('a', 'a.b', 'a.b.c'));
console.log(createObject());
console.log(createObject('')); // note: not handled properly
The last one is not handled properly, but to me it looks more like an invalid input.
Tests
I've added provided solutions to jsperf test and compiled your TypeScript at Playground but for some reason it doesn't work as intended.
So, here is the benchmark. FYI check results in different browsers.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
I think a plain loop works better here. I don't know TypeScript unfortunately, but I'm pretty sure you can adapt this easily enough:
function createObject(...keys)
let obj = ;
for (let key of keys)
let putInto = obj;
let tokens = key.split('.');
for (let i = 0; i < tokens.length; i++) value;
putInto = putInto[name];
return obj;
add a comment |Â
up vote
0
down vote
I think a plain loop works better here. I don't know TypeScript unfortunately, but I'm pretty sure you can adapt this easily enough:
function createObject(...keys)
let obj = ;
for (let key of keys)
let putInto = obj;
let tokens = key.split('.');
for (let i = 0; i < tokens.length; i++) value;
putInto = putInto[name];
return obj;
add a comment |Â
up vote
0
down vote
up vote
0
down vote
I think a plain loop works better here. I don't know TypeScript unfortunately, but I'm pretty sure you can adapt this easily enough:
function createObject(...keys)
let obj = ;
for (let key of keys)
let putInto = obj;
let tokens = key.split('.');
for (let i = 0; i < tokens.length; i++) value;
putInto = putInto[name];
return obj;
I think a plain loop works better here. I don't know TypeScript unfortunately, but I'm pretty sure you can adapt this easily enough:
function createObject(...keys)
let obj = ;
for (let key of keys)
let putInto = obj;
let tokens = key.split('.');
for (let i = 0; i < tokens.length; i++) value;
putInto = putInto[name];
return obj;
answered Jun 5 at 10:16
Máté Safranka
3315
3315
add a comment |Â
add a comment |Â
up vote
0
down vote
In general case this always maps to O(n2). You may introduce some complex optimisations but this yields to long hardly readable code. Are you sure you will benefit from this?
I am a huge fan of CoffeeScript language and both CoffeeScript and TypeScript do a lot of hidden work so it is crucial to see the compiled JavaScript. Also, if your primary concearn is perfomance you will benefit greatly from plain JavaScript solution.
So here is my attempt on it. It is simular to Máté Safranka solution (which is quite nice and readable). It uses Array.prototype.reduce
to remove all local variables in favor of function arguments:
function createObject(...pathes)
return pathes.reduce(function (obj, path)
path.split('.').reduce((obj, key) => obj[key] = obj[key] , );
// Some tests
console.log(createObject('a.b.c.d', 'hello.world', 'test'));
console.log(createObject('a', 'a.b', 'a.b.c'));
console.log(createObject());
console.log(createObject('')); // note: not handled properly
The last one is not handled properly, but to me it looks more like an invalid input.
Tests
I've added provided solutions to jsperf test and compiled your TypeScript at Playground but for some reason it doesn't work as intended.
So, here is the benchmark. FYI check results in different browsers.
add a comment |Â
up vote
0
down vote
In general case this always maps to O(n2). You may introduce some complex optimisations but this yields to long hardly readable code. Are you sure you will benefit from this?
I am a huge fan of CoffeeScript language and both CoffeeScript and TypeScript do a lot of hidden work so it is crucial to see the compiled JavaScript. Also, if your primary concearn is perfomance you will benefit greatly from plain JavaScript solution.
So here is my attempt on it. It is simular to Máté Safranka solution (which is quite nice and readable). It uses Array.prototype.reduce
to remove all local variables in favor of function arguments:
function createObject(...pathes)
return pathes.reduce(function (obj, path)
path.split('.').reduce((obj, key) => obj[key] = obj[key] , );
// Some tests
console.log(createObject('a.b.c.d', 'hello.world', 'test'));
console.log(createObject('a', 'a.b', 'a.b.c'));
console.log(createObject());
console.log(createObject('')); // note: not handled properly
The last one is not handled properly, but to me it looks more like an invalid input.
Tests
I've added provided solutions to jsperf test and compiled your TypeScript at Playground but for some reason it doesn't work as intended.
So, here is the benchmark. FYI check results in different browsers.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
In general case this always maps to O(n2). You may introduce some complex optimisations but this yields to long hardly readable code. Are you sure you will benefit from this?
I am a huge fan of CoffeeScript language and both CoffeeScript and TypeScript do a lot of hidden work so it is crucial to see the compiled JavaScript. Also, if your primary concearn is perfomance you will benefit greatly from plain JavaScript solution.
So here is my attempt on it. It is simular to Máté Safranka solution (which is quite nice and readable). It uses Array.prototype.reduce
to remove all local variables in favor of function arguments:
function createObject(...pathes)
return pathes.reduce(function (obj, path)
path.split('.').reduce((obj, key) => obj[key] = obj[key] , );
// Some tests
console.log(createObject('a.b.c.d', 'hello.world', 'test'));
console.log(createObject('a', 'a.b', 'a.b.c'));
console.log(createObject());
console.log(createObject('')); // note: not handled properly
The last one is not handled properly, but to me it looks more like an invalid input.
Tests
I've added provided solutions to jsperf test and compiled your TypeScript at Playground but for some reason it doesn't work as intended.
So, here is the benchmark. FYI check results in different browsers.
In general case this always maps to O(n2). You may introduce some complex optimisations but this yields to long hardly readable code. Are you sure you will benefit from this?
I am a huge fan of CoffeeScript language and both CoffeeScript and TypeScript do a lot of hidden work so it is crucial to see the compiled JavaScript. Also, if your primary concearn is perfomance you will benefit greatly from plain JavaScript solution.
So here is my attempt on it. It is simular to Máté Safranka solution (which is quite nice and readable). It uses Array.prototype.reduce
to remove all local variables in favor of function arguments:
function createObject(...pathes)
return pathes.reduce(function (obj, path)
path.split('.').reduce((obj, key) => obj[key] = obj[key] , );
// Some tests
console.log(createObject('a.b.c.d', 'hello.world', 'test'));
console.log(createObject('a', 'a.b', 'a.b.c'));
console.log(createObject());
console.log(createObject('')); // note: not handled properly
The last one is not handled properly, but to me it looks more like an invalid input.
Tests
I've added provided solutions to jsperf test and compiled your TypeScript at Playground but for some reason it doesn't work as intended.
So, here is the benchmark. FYI check results in different browsers.
function createObject(...pathes)
return pathes.reduce(function (obj, path)
path.split('.').reduce((obj, key) => obj[key] = obj[key] , );
// Some tests
console.log(createObject('a.b.c.d', 'hello.world', 'test'));
console.log(createObject('a', 'a.b', 'a.b.c'));
console.log(createObject());
console.log(createObject('')); // note: not handled properly
function createObject(...pathes)
return pathes.reduce(function (obj, path)
path.split('.').reduce((obj, key) => obj[key] = obj[key] , );
// Some tests
console.log(createObject('a.b.c.d', 'hello.world', 'test'));
console.log(createObject('a', 'a.b', 'a.b.c'));
console.log(createObject());
console.log(createObject('')); // note: not handled properly
answered Jul 21 at 15:10
sineemore
1,173217
1,173217
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195838%2fcreating-nested-objects-from-string%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Can you post some example input and output? It would make it a lot easier to understand.
â Máté Safranka
Jun 4 at 22:11
Typescript chokes on this as soon as I paste it into any playground I'm familiar with, even ignoring the compiler errors, the code itself doesn't seem to work.
Cannot set property 'a' of undefined
given your first example.â Gerrit0
Jun 6 at 1:25