Nested array formation with string in javascript - javascript

I have a string as "a.b.c.d:50" so i want to form an array with the above string as t[a][b][c][d]=50. so i have tried to split the code and form but this length of n values will generate dynamically. please let me know how we can achieve this.for fixed arrays i tried as below but not able to make this as for n number of arrays.
var str1="a.b.c.d:50";
var str=str1.split(":");
var dump=str[0].split(".");
t[dump[0]][dump[1]][dump[2]][dump[3]]=dump[4]
then result will be t[a][b][c][d]=50

You could take the JSON string, parse it and iterate all key/value pairs for a nested structure by saving the last key and crate new objects if not exist and assign the vlaue with the last property.
function setValue(object, path, value) {
var last = path.pop();
path.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
}
var json = '{"subscriber.userTier.segment": "Red"}',
object = {};
Object
.entries(JSON.parse(json))
.forEach(([keys, value]) => setValue(object, keys.split('.'), value));
console.log(object);

Are you able to use ES6? This is something I just wrote quickly
var t = {a:{b:{c:{d:0}}}};
var str = "a.b.c.d:50"
var [chain, value] = str.split(':')
var parts = chain.split('.');
parts.slice(0, -1).reduce((c, v) => c[v], t)[parts[parts.length - 1]] = value;
console.log(t.a.b.c.d); // logs "50"
It works, however there is no error handling. If t['a']['b'] is undefined for example then you will get an uncaught TypeError, also if the string is in the incorrect format etc, it won't work.
At it's heart it uses reduce on the array ['a', 'b', 'c']. We pass t as the initial value for the reducer and then for each item in the array it does currentValue = currentValue[nextPart]. This will get you the object c, we then look at the last value in the parts array and set that property currentValue[lastPart] = value
That's a brief overview, hopefully you understand the rest of what's going on. If not feel free to ask :)

Quick and Dirty way of converting a string to a JSON object, if the string is constructed as a valid object.
var str = "a.b.c.d:50";
str = str.replace(/([a-z]){1}/gi, "\"$1\"");
str.split(".").forEach(function (value) {
str = str.replace(/\.(.*?)$/, ":{$1}");
});
var ar = JSON.parse("{"+str+"}");
console.log(ar);

Related

How to create javascript object from concatenated key value pairs

I need to create an object from a variable created with concateneated key value pairs.
HardCoded (it is an array as dataSource for a jquery datatable), it looks like this:
obj = {
totalValue: valVar,
totalReceiptValue: receiptVar
}
dataSourceArray.push(obj);
My variable is:
cumulator ="totalValue:8573.0000,totalReceiptValue:3573.00,"
I've tried this,
var obj = {};
const name = "";
const value = cumulator;
obj[name] = value;
dataSourceArray.push(obj);
but then I have an extra key i.e. "": in the object which of course fails for my requirements.
How do I do this?
Thanks
Assuming that there are no extra : or , signs that could mess with the logic, it can be achieved simply by spliting the strings and using the built in method Object.prototype.fromEntries
const input = "totalValue:8573.0000,totalReceiptValue:3573.00,";
const output = Object.fromEntries( // combine entries into object
input.split(",") // divide into pairs
.filter(Boolean) // remove empty elements (comma at the end)
.map((el) => el.split(":")) // divide the pair into key and value
)
console.log(output)
There apparently being some problems with IE and Edge, the code above can be fixed by writing own implementation of from Entries and opting to not use arrow functions.
const input = "totalValue:8573.0000,totalReceiptValue:3573.00,";
const entries = input.split(",") // divide into pairs
const output = {};
for (let i=0; i<entries.length; i++) {
if (!entries[i]) continue; // remove empty elements (comma at the end)
const [key, val] = entries[i].split(":"); // divide the pair into key and value
output[key]=val; // combine entries into object
}
console.log(output)
You can simply use split, map reduce functions.
Try this.
const input = "totalValue:8573.0000,totalReceiptValue:3573.00,";
const result = input.split(',').filter(Boolean).map(function(text) {
return text.split(':')
}).reduce(function(acc, curr) {
acc[curr[0]] = curr[1]
return acc
}, {})
console.log(result)

FIlter the text content and try to convert filtered content into JSON

I'm having an input in the form of a string variable msg.payload as given below.
Hi Team,
Below are the details of for the given source platform.
name=abc
status=Active
company=Discovery
FromDate=6/05/2020
ToDate=20/05/2020
Please do the needful ASAP
Thanks & Regards,
xyz
I want to take only the
name=abc
status=Active
company=Discovery
FromDate=6/05/2020
ToDate=20/05/2020
ignore the rest and then convert it into JSON using JavaScript like
{"name":"abc", "status":"Active","company":"ABCD" ,"FromDate":"6/05/2020","ToDate":"20/05/2020"}
How can I accomplish it? All the data in the input will be of the form key=value.
You can take advantage of several built-in JavaScript string and array functions.
Convert input to an array of lines with String.prototype.split():
const lines = input.split('\n');
Filter out lines that don't contain an equals sign with Array.prototype.filter():
const kvPairs = lines.filter(line => line.includes('='));
Use Array.prototype.forEach() and String.prototype.split() to load the object with key-value properties:
let object = {};
kvPairs.forEach(line => {
[key, val] = line.split('=');
object[key] = val;
});
Putting it all together:
const input = 'Hi Team,\nBelow are the details of for the given source platform.\nname=abc\nstatus=Active\ncompany=Discovery\nFromDate=6/05/2020\nToDate=20/05/2020\nPlease do the needful ASAP\nThanks & Regards,\nxyz';
const lines = input.split('\n');
const kvPairs = lines.filter(line => line.includes('='));
let object = {};
kvPairs.forEach(line => {
[key, val] = line.split('=');
object[key] = val;
});
console.log('object:', object);

Javascript array - split

I have a text file in which I have data on every line. It looks like this:
number0;text0
number1;text1
number2;text2
..and so on
So I loaded that text file into a variable via xmlhttprequest and then I converted it into an array using split by "\n" so now the result of lineArray[0] is number0;text0.. And now what I need is to split that array again so I could use number0 and text0 separately.
My idea being that I want to get the text0 by searching number0 for example lineArray[i][1] gives me texti..
Any ideas how to proceed now?
Thanks
You need to do an additional split on ; as split(';') so that lineArray[0][1], lineArray[1][1] and so on gives you text0, text1 and so on.
var str = `number0;text0
number1;text1
number2;text2`;
var lineArray = str.split('\n').map(function(item){
return item.split(';');
});
console.log(lineArray);
console.log(lineArray[0][1]);
console.log(lineArray[1][1]);
Knowing I'm late, still making a contribution.
As everyone else said, split it again.
let text = "number0;text0\nnumber1;text1\nnumber2;text2"
let data = text.split('\n');
var objects = {};
for (var i = 0; i < data.length; i++) {
let key = data[i].split(';')[0]; // Left hand value [Key]
let value = data[i].split(';')[1]; // Right hand value [Value]
// Add key and value to object
objects[key] = value;
}
// Access by property
console.log(objects);
Using forEach
let text = "number0;text0\nnumber1;text1\nnumber2;text2"
let data = text.split('\n');
var objects = {};
data.forEach((elem) => {
let key = elem.split(';')[0]; // Left hand value [Key]
let value = elem.split(';')[1]; // Right hand value [Value]
objects[key] = value;
});
// Access by property
console.log(objects);
Just use split again with ";", like that:
myVar = text.split(';');
like #Teemu, #Weedoze and #Alex said
Convert the array into an object
Make an object out of it with another String split. To do so you can use the .reduce method to convert the array of strings into an object.
const strings = ['number0;text0', 'number1;text1', 'number3;text3', 'number4;text4'] ;
const obj = strings.reduce((acc,curr) => {
const [key, value] = curr.split(';');
acc[key] = value;
return acc;
}, {});
console.log(obj)
This way you can access text4 buy calling obj['number4'].
More about .reduce
The reduce method works by looping through strings
on each step acc is the accumulator: it contains the object that is getting filled with key/value pairs.
cur is the current item in the step
const [key, value] = curr.split(';') will to split the string into two strings and assign each to a seperate variable: key and value. It's called destructuring assignment
then I assign the key/value pair to the accumulator
the .reducemethod will return the accumulator on his state on the last step of the loop
Something like this could do the trick:
let a = "number0;text0\nnumber1;text1\nnumber2;text2";
let lines = a.split('\n');
let vals = [];
for(let line of lines) {
vals.push(line.split(';'))
}
console.log(vals); // Output
The last four lines create an empty array and split on the ';' and append that value to the vals array. I assume you already have the something like the first 2 lines

JavaScript. How can I parse a string of vars and turn it into an object with properties

I am trying to parse a string in JS with a series of vars inline. The goal is to turn those vars into an object with name value pairs.
Example:
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
I know I can parse the original string to get an array of name value pairs like this:
varArr = hwStr.split("+");
When I print that array I would get:
>color=blue,
>coreCnt=4,
>shell=aluminum,
>wireless=false
In order to create this object manually it would look like:
var hwSpec = {color: 'blue', coreCnt: 4, shell: 'aluminum', wireless: false};
My question is, how can I use a foreach statement to create an object that would have these as name value pairs.
To be fair JS is not my language, but I know that I SHOULD know this... This is probably a noob Question, any help would be great.
Gary C aka the UnKulMunki
After splitting on the plus signs, you can .reduce() the resulting array to process each key=value pair and add to an object:
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
var obj = hwStr.split("+").reduce(function(o, item) {
item = item.split("=");
o[item[0]] = item[1];
return o;
}, {});
console.log(obj);
This is similar to using .forEach(), except instead of creating an empty object in a variable before calling .forEach() the empty object is passed as an argument to .reduce(). For this particular problem it doesn't make much difference, but in some cases .reduce() saves you having to create a temporary working variable.
EDIT: Note that my code creates all property values as strings - I don't think there's any way to know whether false should be treated as the boolean false or the string "false", unless you want to assume that all values that can be parsed as boolean or number should be treated as boolean or number.
First, you split the string at the + so you get an array of key/value pairs.
Then, you loop through those pairs and split each pair at the = to separate the key from the value. Then you assign the key as a property name and the value as the property value.
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
// Split the string into an array of key/value pairs
var pairs = hwStr.split("+");
// Set up a new, empty object
var newObj = {};
// Loop through the key/value pairs array. The .forEach method takes
// a function as an argument that, itself, receives a value representing
// the current array item being iterated (a single key/value pair from
// the array in this case).
pairs.forEach(function(pair){
// Create a new property on the object with the key of the current pair
// and a value of the value of the current pair.
newObj[pair.split("=")[0]] = pair.split("=")[1];
});
console.log(newObj);
To do this, you have to use JSON's parse method to turn the string to javaScript object literal, this is how to do it:
var arr = hwStr.split("+");
var temp_arr = null;
var hwSpec = null;
var stringToConv = '{'; //string to convert to object literal
//iterate through the array
for (var i = 0; i < arr.length; i++){
temp_arr = arr[i].split("=");
stringToConv += '"' + temp_arr[0] + '":"' + temp_arr[1] + '"';
//check if is the last string in the arr
if (i === arr.length - 1){
stringToConv += '}'
}
else { //add comma
stringToConv += ",";
}
}
//convert to object using JSON
hwSpec = JSON.parse(stringToConv);
//your code here

Creating a two-dimensional object from a string of values

In JavaScript, how would I create a two-dimensional object from a string of values, in which the first value would be the name, the last is the content, and all other values in between are properties?
For example, I have a string "capitals,Asia,China,Beijing" and I want the code to split this string into four values and create an object capitals["Asia","China"] = "Beijing";.
How could I do that?
In a complete code piece that would look like this:
<script>
Values = "capitals,Asia,China,Beijing";
Values = Values.split(",");
alert(capitals["Asia","China"]);
</script>
I want the alert box to show me the word Beijing.
How could I do that?
JavaScript does not have two-dimensional arrays or objects that you can access using array[index1, index2] as in some other languages. To do this, you have to use nested objects/arrays, such as
capitals["Asian"]["China"]
To create these, you can do something like:
function makeEntry(obj, str) {
const parts = str.split(','); // array of comma-delimited values
const value = parts.pop(); // final value ("Beijing")
const final = parts.pop(); // final property ("China")
// Find nested property, creating empty object if not there.
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (!(parts in obj)) obj[part] = {};
obj = obj[part];
}
// Set final value.
obj[final] = value;
}
const data = {};
makeEntry(data, "capitals,Asian,China,Beijing");
console.log(data);
console.log(data.capitals["Asian"]["China"]);
This code will work even if there are more levels, such as "capitals,Asia,East Asia,China,Beijing".
Note that there is no way to create a variable in JS given a name. Therefore, we provide an initial object, and build the nest structure within it.
Another approach
Another approach is to create a single-level object with keys such as "capitals,Asian,China". That's easier to create, but might be more inconvenient to access. For example, there would be no easy way to find all the Asian capitals. Below, I'm using regexp to pick apart the input into the first part and the final value.
function makeEntry(obj, str) {
const [, key, value] = str.match(/(.*),([^,]+)$/);
obj[key] = value;
}
const data = {};
makeEntry(data, "capitals,Asian,China,Beijing");
console.log(data);
console.log(data["capitals,Asian,China"]);
You can use WeakMap to set the key of the WeakMap object to an object; Array.prototype.shift(), Array.prototype.splice(), Array.prototype.pop() to set the value of the WeakMap object instance.
let Values = "capitals,Asian,China,Beijing";
Values = Values.split(",");
const capitals = {[Values.shift()]:Values.splice(0, 2)};
const wm = new WeakMap;
wm.set(capitals, Values.pop());
console.log(wm.get(capitals));
You can alternatively set the property of an object to the result of JSON.stringify() called on Values.splice(1, 2)
let Values = "capitals,Asian,China,Beijing";
Values = Values.split(",");
const key = JSON.stringify(Values.splice(1, 2));
console.log(key);
const map = {[Values.shift()]:{[key]:Values.pop()}};
console.log(map.capitals[key]);

Categories

Resources