Splitting string to object in JS - javascript

I get a response from a server like this:
3S1,https://lekcjaplus.vulcan.net.pl
TA1,https://uonetplus-komunikacja.umt.tarnow.pl
OP1,https://uonetplus-komunikacja.eszkola.opolskie.pl
RZ1,https://uonetplus-komunikacja.resman.pl
GD1,https://uonetplus-komunikacja.edu.gdansk.pl
P03,https://efeb-komunikacja-pro-efebmobile.pro.vulcan.pl
P01,http://efeb-komunikacja.pro-hudson.win.vulcan.pl
P02,http://efeb-komunikacja.pro-hudsonrc.win.vulcan.pl
P90,http://efeb-komunikacja-pro-mwujakowska.neo.win.vulcan.pl
I want to convert it to an object like this:
"3S1": "https://lekcjaplus.vulcan.net.pl",
"TA1": "https://uonetplus-komunikacja.umt.tarnow.pl",
"OP1": "https://uonetplus-komunikacja.eszkola.opolskie.pl",
"RZ1": "https://uonetplus-komunikacja.resman.pl",
"GD1": "https://uonetplus-komunikacja.edu.gdansk.pl",
"P03": "https://efeb-komunikacja-pro-efebmobile.pro.vulcan.pl",
"P01": "http://efeb-komunikacja.pro-hudson.win.vulcan.pl",
"P02": "http://efeb-komunikacja.pro-hudsonrc.win.vulcan.pl",
"P90": "http://efeb-komunikacja-pro-mwujakowska.neo.win.vulcan.pl"
What's the simplest way to achieve this?

You can split by new line and use reduce
let str = `3S1,https://lekcjaplus.vulcan.net.pl
TA1,https://uonetplus-komunikacja.umt.tarnow.pl
OP1,https://uonetplus-komunikacja.eszkola.opolskie.pl
RZ1,https://uonetplus-komunikacja.resman.pl
GD1,https://uonetplus-komunikacja.edu.gdansk.pl
P03,https://efeb-komunikacja-pro-efebmobile.pro.vulcan.pl
P01,http://efeb-komunikacja.pro-hudson.win.vulcan.pl
P02,http://efeb-komunikacja.pro-hudsonrc.win.vulcan.pl
P90,http://efeb-komunikacja-pro-mwujakowska.neo.win.vulcan.pl`;
let result = str.split(/\n/).reduce((c, v) => {
if( v.trim() !== '' ) {
let [k, o] = v.trim().split(',');
c[k] = o;
}
return c;
}, {});
console.log(result);
In case you have multiple , on each line, you can deconstruct the array and join(',')
let result = str.split(/\n/).reduce((c,v)=>{
if( v.trim() ) {
let [k,...o] = v.trim().split(',');
c[k] = o.join(',');
}
return c;
},{});

First of all, you need to split the string into lines
Then split every line into two parts, the first part will be a key and the second one will be the value of the same key.
let input = `3S1,https://lekcjaplus.vulcan.net.pl
TA1,https://uonetplus-komunikacja.umt.tarnow.pl
OP1,https://uonetplus-komunikacja.eszkola.opolskie.pl
RZ1,https://uonetplus-komunikacja.resman.pl
GD1,https://uonetplus-komunikacja.edu.gdansk.pl
P03,https://efeb-komunikacja-pro-efebmobile.pro.vulcan.pl
P01,http://efeb-komunikacja.pro-hudson.win.vulcan.pl
P02,http://efeb-komunikacja.pro-hudsonrc.win.vulcan.pl
P90,http://efeb-komunikacja-pro-mwujakowska.neo.win.vulcan.pl`;
output = input.split(/\n/g);
output = output.reduce((acc, item) => {
item = item.split(",");
acc[item[0]] = item[1];
return acc;
}, {})
console.log(output);

Related

Looping data from json using Array

I'm trying to write a function but I doesn't make it. This function works like that
Input: changeSetting("a>b>c","hello")
After that "setting" named value change from {} to {"a":{"b":{"c":"hello"}}}
If input is changeSetting("a","hello") json become {} to {"a":"hello"}
My last code attempt:
function changeSetting(name,val) {
if (name.includes(">")) {
name = name.split('>')
let json = {}
name.map((el,i)=>{
let last = ""
name.filter(el=>!name.slice(i+1).includes(el)).map(el=> {
if(last!="") {
json[el] = {}
}})
})
}
}
How can we make this ? (Optimization not important but if is it good for me)
const changeSetting = (setting, target) => {
if (setting.length < 2) {
return {
[setting]: target
}
} else {
const keys = setting.split('>');
return keys.reduceRight((acc, curr, i) => {
console.log(acc);
if(i === keys.length - 1) {
return acc = {[curr] : target}
}
return acc = { [curr]: acc };
}, {})
}
}
console.log(changeSetting('a', 'hello'));
console.log(changeSetting('a>b>c', 'hello'));
function changeSetting(inputProperties, value) {
let result;
const properties = inputProperties.split(">");
result = `{${properties
.map((property) => `"${property}":`)
.join("{")}"${value}"${"}".repeat(properties.length)}`;
return result;
}
changeSetting("a>b>c", "hello");
changeSetting("a", "hello");
As you work with strings - you may try to use JSON like this:
function changeSetting(name, val) {
const keys = name.split(">");
return JSON.parse(
[
"{",
keys.map((key) => `"${key}"`).join(":{"),
":",
`"${val}"`,
"}".repeat(keys.length),
].join("")
);
}
There's multiple ways to do this, I've commented the snippet
const changeSetting = (name, val) => {
// Split and reverse the name letters
const nameSplit = name.split('>').reverse();
// Set up the inner most object
let newObj = {[nameSplit[0]]:val}
// Now remove the first letter and recurse through the rest
nameSplit.slice(1).forEach((el, idx) => newObj = {[el]: newObj});
console.log(newObj);
}
changeSetting("a>b>c", "hello")
changeSetting("a", "hello")
changeSetting("a>b>c>d>e>f>g", "hello")
You can create an array by splitting name on all > with String.prototype.split(), and then Array.prototype.reduceRight() the created array of elements with an object initial value {} and adding key value pairs but on the last element the value should be variable val.
Code:
const changeSetting = (name, val) => name
.split('>')
.reduceRight((a, c, i, arr) => ({
[c]: i === arr.length - 1 ? val : a
}), {})
console.log(changeSetting('a>b>c', 'hello'))
console.log(changeSetting('a', 'hello'))
console.log(changeSetting('a>b>c>d>e>f>g', 'hello'))

array of strings to tree data structure?

There is data returned from server containing an array of strings as hierarchy like this:
var array = [
"house.bedroom.bed",
"house.kitchen.spoon",
"house.kitchen.knife",
"house.bedroom.sofa",
"house.bedroom.tv",
"plants.trees",
"house.birds.parrot.grey"
]
i have successful made a tree data structure as object out of it to make Output the data in tree form below:
house
bedroom
bed
sofa
tv
kitchen
spoon
knife
birds
parrot
grey
plants
trees
and is there any way to pick a string? for example of asked "kitchen" i want to return all related to that string like this:
house.kitchen.knife
house.kitchen.spoon
Here the codes that i learned:
function find([key, values], string, temp = []) {
var result;
temp = temp.concat(key);
if (key === string) {
return temp.slice(1).join('.');
}
values.some(a => result = find(a, string, temp));
return result;
}
var result = array.reduce((r, s) => {
('root.' + s).split('.').reduce((a, item) => {
var array = a.find(([v]) => v === item);
if (!array) {
a.push(array = [item, []]);
}
return array[1];
}, r);
return r;
}, []).pop();
console.log(find(result, 'kitchen'));
console.log(result);
my output is:
house.kitchen
I propose to filter the original array
const data = ["house.bedroom.bed","house.kitchen.spoon", "house.kitchen.knife","house.bedroom.sofa","house.bedroom.tv",
"plants.trees","house.birds.parrot.grey"];
const result = data.filter((path) => path.split('.').includes('kitchen'));
console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}
I believe I understand what you're asking. I would solve this problem with recursion.
function parse(items) {
return items.reduce((acc, item) => {
const k = item.slice(0, item.indexOf('.'))
const v = item.slice(item.indexOf('.') + 1).split('.')
const newItem = {
[k]: v.length > 1 ? parse(v) : v
}
return Object.assign(acc, newItem)
}, { })
}
This is not a complete solution but should get the general idea across. For each item in the array, split it off into a key and a value. The key will be the string before the first ., and the value with either be the single string after that ., or an object containing children.

Convert string into key-value pairs in an array

I have a string:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
I want to convert this string to key-> value pairs in an array.
[
dtstart: 20190514T111500Z,
freq: daily,
interval: 1
]
I know I can take the string and split it based on the semicolon:
var array = rrule.split(";");
... but this leaves me with an array like this:
[
"DTSTART=20190514T111500Z",
"FREQ=DAILY",
"INTERVAL=1"
]
I guess I need another step to map out the keys/values, but I get lost at this point.
Ideally, for the string I want to be able to easily access what dtstarts equals, what interval equals, what other variables equal and so on.
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let obj = {};
for (let entry of str.split(";")) {
let pair = entry.split("=");
obj[pair[0]] = pair[1];
}
console.log(obj);
You already know how to split on the ; to get an array, from there you can just aggregate (using reduce) to get an object:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
var result = rrule.split(";").reduce( (obj,item) => {
let [key,value] = item.split("=");
obj[key] = value;
return obj;
},{});
console.log(result["DTSTART"])
console.log(result["FREQ"])
console.log(result["INTERVAL"])
You were correct to start with split first, this would then return you an array of strings.
To easily convert them, just use map, to return the split the single strings once more, and then return an object based on the property name you would like to give it and it's value
function createKeyValuePairFromString( str ) {
return str.split(';').map( item => {
const splitted = item.split('=');
return { [splitted[0]]: splitted[1] };
});
}
console.log( createKeyValuePairFromString("DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1") );
Use array created and split it again with =
function convertToObject(cookieString) {
const cookieObj = {};
if (!cookieString && typeof cookieString !== 'string') return cookieObj;
const arr = cookieString.split(';');
arr.forEach(record => {
if (record.includes('=')) {
const [key, value] = record.split('=');
cookieObj[key.trim()] = value;
}
});
return cookieObj;
}
You can use it like the code below:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let finalObj = {};
rrule.split(';').forEach(i => finalObj[i.split('=')[0]] = i.split('=')[1]);
console.log('finalObj',finalObj);
Here I'm first splitting with ';' so consider the first item to be DTSTART=20190514T111500Z Then on splitting with = I get finalObject['DTSTART'] = 20190514T111500Z
Using forEach()
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let obj = {};
let strArr = str.split(';')
strArr.forEach((str) => {
let [key, value] = str.split('=')
obj[key] = value;
});
console.log(obj);
Here's a fairly simple version, returning an object, not an array:
const toObj = str => str
.split (';')
.map ( s => s .split ('=') )
.reduce ( (a, [k, v]) => ({...a, [k]: v}), {} )
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
console.log (
toObj(str)
)
One of the reasons I like the library is that we can write this sort of logic more simply. In Ramda (disclaimer: I'm one of the authors), it might look like this:
const toObj = pipe ( split (';'), map (split ('=') ), fromPairs)
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
console.log (
toObj(str)
)
<script src="https://bundle.run/ramda#0.26.1"></script><script>
const {pipe, split, map, fromPairs} = ramda; </script>
var str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
// string splitting rule
const rule = (string, delimiter) => string.split(delimiter);
const result = rule(str, ';').reduce((acc, s) => {
const [key, value] = rule(s, '=');
acc[key] = value;
return acc;
}, {});
console.log(result);

How to convert the string to object in JavaScript?

I need to convert this string into object
var str = "res=[xyz=name,abc=address]";
I need below output :
var obj = {xyz: "name",abc:"address"}
I tried to convert this by using json.parse and split but I can't get the result .can anyone help to do this ?
This code works with the string given. It is also very readable for noobs
var str = "res=[xyz=name,abc=address]";
str = str.split("res=")[1]
.replace("[",'{"')
.replace("]",'"}')
.replace(/=/g,'":"')
.replace(/,/g,'","');
res = JSON.parse(str);
console.log(str,"\n",res);
One more Implementation:
//str format "res=[xyz=name,abc=address]"
function stringToObject(str){
const extractedStr = str.substring(str.indexOf("[")+1,str.indexOf("]")-1);
return extractedStr.split(",").reduce((acc,keyVal)=>{
acc[keyVal.split("=")[0]] = keyVal.split("=")[1];
return acc;
},{});
}
console.log(stringToObject("res=[xyz=name,abc=address]"));
Here's a way to do it:
// format your input like this, comma separated, and key=val
const str = "xyz=name,abc=address"
const obj = str.split(',').reduce((acc, keyVal) => {
const [key, val] = keyVal.split('=')
acc[key] = val
return acc
}, {})
console.log(obj)
// { xyz: "name", abc: "address" }
Another implementation
let str = "res=[xyz=name,abc=address]";
let convertStrToObject = (str) => {
return str
.substring(5, str.length - 1)
.split(",")
.reduce((acc, item) => {
acc[item.split("=")[0]] = item.split("=")[1];
return acc;
}, {});
};
console.log(convertStrToObject(str));

JavaScript function to split the string and return the combination in an array

I'm trying to write a JavaScript function to split a string by its delimiter ('/') and wanted to return its path combination in an array.
Input:
"Global/Europe/UK/London"
Desired Output:
["Global","Global/Europe","Global/Europe/UK"]
I tried the below recursive function, but for some reason the array contains only a single value.
function splitPath(str) {
var output = [];
if (str.lastIndexOf('/') !== -1) {
str = str.split("/").slice(0, -1).join("/");
output.push(str);
splitPath(str);
}
//console.log(output);
return output;
}
Please let me know if there's any straight way to achieve this in JavaScript.
Thanks.
Using Array#reduce
let input = "Global/Europe/UK/London";
let output = input.split("/").slice(0, -1).reduce((acc, item, index) => {
acc.push(index ? acc[index - 1] + '/' + item : item);
return acc;
}, []);
console.log(output);
You could split the string and map with the parts from the beginning by using only the parts without the last one.
var string = "Global/Europe/UK/London",
grouped = string
.split('/')
.slice(0, -1)
.map(function (_, i, a) {
return a.slice(0, i + 1).join('/');
});
console.log(grouped);
Here's a way to split and then iteratively add the parts:
function splitPath(str) {
const parts = str.split("/");
let head = parts.shift();
const result = [head];
for (const part of parts) {
head += "/" + part;
result.push(head);
}
return result;
}
console.log(splitPath("Global/Europe/UK/London"))
How about this ?
let output = [];
let input = str.split('/');
input.reduce((acc,v, i, arr) => { output.push(acc + "/"+ v ); return acc + "/"+ v; })
'Global/Europe/UK/London'
.split('/')
.map(
(item, i, items) => {
return items.slice(0, i+1).join('/');
}
)

Categories