This question already has answers here:
How do I split a string, breaking at a particular character?
(17 answers)
Generic solution to create an Object of unknown deepth from an Array
(1 answer)
Closed 5 years ago.
Given a JS string: var s = "deep.deeper.deepest", how can I convert this into object like this: deep: {deeper: {deepest: {}}}
const dottedToObj = (str, orig = {}) => (str.split(".").reduce((obj, key) => obj[key] = {}, orig), orig);
Just reduce the array of strings (splitted the original string) into a chain of objects. Or a bit less functional:
function dottedToObj(str){
const root = {};
var acc = root;
for(const key of str.split(".")){
acc = acc[key] = {};
}
return root;
}
A simple loop should work for this, just move through each dotted property while moving down one level in the object:
const s = "deep.deeper.deepest";
function convertToObject(str) {
const result = {};
let inner = result;
for (const key of s.split(".")) {
// Give the object a child with this key
inner[key] = {};
// Set the current object to that child.
inner = inner[key]
}
// Return the original
return result;
}
console.log(convertToObject(s))
Related
This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed last year.
Consider the following JSON object:
{
"data": {
"data2": {
"myProp": "hello"
}
}
}
I need to be able to dynamically access the deep property myProp, but the catch is, that I need to be able to write the deep property as a regular string. i.e:
let sortByThisValue = 'data.data2.myProp'
So I already started:
let propertyArray = sortByThisValue.split('.')
//Do something here
let myVal = data.[data2][myProp] //Or data.data2.myProp
You can access like below
const obj = {
data: {
data2: {
myProp: "hello",
},
},
};
const key = "data.data2.myProp";
const getValue = (obj, key) => {
const keys = key.split(".");
let value = obj;
for (let i = 0; i < keys.length; i++) {
value = value[keys[i]];
if (!value) {
break;
}
}
return value;
};
console.log(getValue(obj, key));
console.log(getValue(obj, 'abc'));
This question already has answers here:
How to set object property (of object property of..) given its string name in JavaScript?
(16 answers)
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 1 year ago.
I am passing a dot separated string into function
console.log( namespace('a.b.c.d.e'))
and expect get next result
//result => "{"a":{"b":{"c":{"d":{"e":{}}}}}}"
my try (I don't know how to do it recursively)
const namespace = (string)=> {
return string.split('.').reduce((acc,el)=>{
acc[el] = {}
},{})
}
const input = "a.b.c.d.e"
const output = input.split('.').reverse().reduce((acc,el)=>{
return {[el]: acc}
},{})
console.log(output)
How about the below iteration approach :-
function namespace(input){
let result = {};
let temp = result;
const inputArr = input.split(".");
inputArr.forEach((ele)=>{
temp[ele] = {};
temp = temp[ele];
})
return result;
}
console.log( namespace('a.b.c.d.e'))
This question already has answers here:
How to get all properties values of a JavaScript Object (without knowing the keys)?
(25 answers)
Closed 2 years ago.
I am working on this code below. I am attempting to retrieve only the values, not the keys. What this is not doing is providing me with the values but the keys. Can you help me to get this to work properly?
Unfortunately I cannot use the object.values() function, therefore I am at a loss right now. Sorry This was not stated when I posted the original.
function values(obj) {
let arr = [];
for (let value in obj) {
arr.push(value);
}
return arr;
}
let nicknames = {a:`Sunny`, b:`Weirdo`, c:`Chicken`,d:`Tokyo`}
let nicknameValues = values(nicknames)
console.log(nicknameValues)
You can try:
arr.push(obj[value]);
Demo:
function values(obj) {
let arr = [];
for (let value in obj) {
arr.push(obj[value]);
}
return arr;
}
let nicknames = {a:`Sunny`, b:`Weirdo`, c:`Chicken`,d:`Tokyo`}
let nicknameValues = values(nicknames)
console.log(nicknameValues);
Or
const result = Object.values({a:`Sunny`, b:`Weirdo`, c:`Chicken`,d:`Tokyo`});
console.log(result);
Demo:
const result = Object.values({a:`Sunny`, b:`Weirdo`, c:`Chicken`,d:`Tokyo`});
console.log(result);
You can use Object.values:
const values = Object.values({a:`Sunny`, b:`Weirdo`, c:`Chicken`,d:`Tokyo`});
console.log(values);
Or you can change you function values
arr.push(obj[value]);
This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
access object through dot-syntax string path
(2 answers)
Access object child properties using a dot notation string [duplicate]
(13 answers)
Closed 4 years ago.
I am writing a function to convert array to List using Javascript.
If the input array is as below:
let inputArray = [1,2,3]
The output object should be like the below:
let outputList = {
value: 1,
rest: {
value: 2,
rest: {
value : 3,
rest: null } } }
I have the below function that accepts a nested object as its parameter and returns a string that represents where in the object, the property is null:
function getLastValue(object) {
let s = '';
if (object.rest) {
return s += '[rest]' + getLastValue(object.rest);
} else {
return s;
}
And the below function that converts an array to a list:
var list = {value: '', rest: null};
function constructList(arr) {
for (let prop of arr) {
let lastValue = getLastValue(list);
`${list}${lastValue}`.value = prop;
`${list}${lastValue}`.rest = null;
}
return list;
}
The constructList function fails to work as ${list}${lastValue} is a string. I need to convert the above from
'list[rest][rest]'
to
list[rest][rest]
Any help is appreciated!
This would be a great place to use reduceRight - construct the innermost object first, and have it be the new value of the accumulator, which is assigned to the next innermost object's rest property, and so on:
const constructList = arr => arr.reduceRight(
(rest, value) => ({ value, rest }),
null
);
console.log(
constructList([1, 2, 3])
);
To fix your original code, rather than constructing a string that attempts to refer to the nested object, iterate through the nested structure to find the innermost rest property instead, and return the object that doesn't contain a truthy rest property:
function getLastValue(obj) {
while (true) {
if (!obj.rest) return obj;
obj = obj.rest;
}
}
var list = {
value: '',
rest: null
};
function constructList(arr) {
for (let prop of arr) {
const nestedObj = getLastValue(list);
nestedObj.value = prop;
nestedObj.rest = {};
}
getLastValue(list).rest = null;
return list;
}
console.log(
constructList([1, 2, 3])
);
This question already has answers here:
Convert a JavaScript string in dot notation into an object reference
(34 answers)
Closed 5 years ago.
I have csv files that I am reading using nodeJS. I convert each file to text before reading.
Each line in the file have data delimited with =.
Each line looks something like
data.location.degree.text=sometexthere
The first portion before the "=" represents an index to a JSON object in my app. My aim is to parse this data and build a JSON representation of it so that the line above becomes
data:{
location:{
degree:{
text: 'sometexthere'
}
}
}
Using javascript/nodejs; How can I convert a string which is supposed to represent a sequence of nested JSON keys, into a JSON object like above?
You could split the path and make a check if the following element exist. If not assign an object to the new property.
Return then the value of the property.
At the end assign the value.
function setValue(object, path, value) {
path = path.replace(/[\[]/gm, '.').replace(/[\]]/gm, ''); //to accept [index]
var keys = path.split('.'),
last = keys.pop();
keys.reduce(function (o, k) { return o[k] = o[k] || {}; }, object)[last] = value;
}
var data = {};
setValue(data, 'location.degree.text', 'sometexthere');
console.log(data);
// result container
var res = {};
// input data
var inp = [
'data.location.degree.text=sometexthere',
'data.otherLocation.degree.otherText=foo',
'data.location.degree.otherText=bar',
'we.can.handle.values.that.are_undefined=',
'we.can.handle.values.that.contain_equals_signs=yes=we=can'
];
// recursive function
var pathToObject = function(resultReference, path)
{
// split path on dots
// e.g. data.location.degree.text=sometexthere
// -> ["data", "location", "degree", "text=sometexthere"]
var splitPathParts = path.split('.');
// if there is only one part, we're at the end of our path expression
// e.g. ["text=sometexthere"]
if (splitPathParts.length === 1){
// split "text=sometexthere" into ["text", "sometexthere"]
var keyAndValue = splitPathParts[0].split('=');
// set foo = bar on our result object reference
resultReference[keyAndValue.shift()] = keyAndValue.join('=');
return;
}
// the first element of the split array is our current key
// e.g. for ["data", "location", "degree", "text=sometexthere"],
// the currentKey would be "data";
var currentKey = splitPathParts.shift();
// if our object does not yet contain the current key, set it to an empty object
resultReference[currentKey] || (resultReference[currentKey] = {});
// recursively call ourselves, passing in
// the nested scope and the rest of the path.
// e.g. { data : {} } and 'location.degree.text=sometexthere'
pathToObject(resultReference[currentKey], splitPathParts.join('.'));
}
for (var i = 0; i < inp.length; i++)
{
pathToObject(res, inp[i]);
}
console.log(res);
ES6 syntax makes things slightly more terse:
'use strict';
const pathToObject = (resultReference, path) => {
let [currentKey, ...restOfPath] = path.split('.');
if (restOfPath.length === 0) {
let [k, ...v] = currentKey.split('=');
resultReference[k] = v.join('=');
return;
}
resultReference[currentKey] || (resultReference[currentKey] = {});
pathToObject(resultReference[currentKey], restOfPath.join('.'));
}
let res = {};
[
'data.location.degree.text=sometexthere',
'data.otherLocation.degree.otherText=foo',
'data.location.degree.otherText=bar',
'we.can.handle.values.that.are_undefined=',
'we.can.handle.values.that.contain_equals_signs=yes=we=can'
].forEach(x => pathToObject(res, x));
console.log(res);