How to convert string in an array? - javascript

From http response I received an object like this:
{"[3, company1]":["role_user"], "[4, company2]":["role_admin"] }
The key is an array...Is there a way in typescript to convert the key
"[3, company1]"
in an array like this
[3, "company1"]
?

You can combine Object.keys with map and transform the string to array with split
let data = {"[3, company1]":["role_user"], "[4, company2]":["role_admin"] }
let keys = Object.keys(data)
.map(
el =>
el.replace('[', '')
.replace(']', '')
.split(',')
.map(el => el.trim())
.map(el => isNaN(parseFloat(el))
? el
: parseFloat(el))
)
console.log("Keys: ", keys)
Here is the fiddle:
https://jsfiddle.net/to38g6cb/1/

What do you want to convert the keys to?
if want to convert it to a normal array then the below should do.
const httpResponse = {
"[3, company1]": ["role_user"],
"[4, company2]": ["role_admin"]
};
const convertedKeys = Object.keys(httpResponse).map(value => {
let keyArray = value.replace("[", "").replace("]", "").split(", ");
return [parseInt(keyArray[0]), keyArray[1]];
});
console.log(convertedKeys);
If the above is not what you wanted, please kindly rephrase your question again.

You can remove the first and last character using slice(1,-1) and split the string at /\s*,\s*/ (comma with optional spaces on either side).
Then convert the first part to a number and return the array
const input = {
"[3, company1]": ["role_user"],
"[4, company2]": ["role_admin"]
}
const output = Object.keys(input).map(k => {
const [n, comp] = k.slice(1,-1).split(/\s*,\s*/)
return [+n, comp]
})
console.log(JSON.stringify(output))

It would have been easier if the company1 part were already quoted, so that you could just use JSON.parse. In fact, let's just do that! Put quotes around the company1 part with search and replace.
let key = `[3, company1]`;
let obj = JSON.parse(key.replace(/[$A-Z_]\w*/gi, '"$&"'))
console.log(obj);
Note: I'm guessing at what characters might be valid and went with something that looks vaguely like a JavaScript identifier. [$A-Z_]\w* Obviously not commas and right square brackets, due to deserialization ambiguity.

Related

How to generate a list of strings from a single string with seperators?

I want to achieve the following:
Given: A string like 'path1.path2.path3';
Wanted result: A list of strings -> [path1, path1.path2, path1.path2.path3];
The order has to be the same, I just need all the "levels". I need this to create a breadcrumb-component for an Angular-Applikation using ui-router. States do have names like "path1.path2", which means path2 is a child of path1.
The problem for me is not the splitting, I know how to achieve that via split. My problem is merging them again like mentioned above.
My first idea was to use array.split to get the single parts of the string. But I'm not sure how to build the loop to add a single partial in each iteration.
Seems like this does what you want:
'path1.path2.path3'
.split('.')
.map((section, i, arr) => [...arr.slice(0, i), section].join('.'));
It splits the strings into sections using . as the delimiter, then for each section, it joins it together with all previous sections, using . as the delimiter.
Try using a reducer for the splitted string. Something like:
const str = "path1.path2.path3";
console.log( str.split(".").reduce( (acc, str, i) =>
[...acc, (i ? `${acc[i - 1]}.${str}` : str)], []) );
There are already some answers here, but i'd like to add mine with reduce:
const string = 'path1.path2.path3'
const paths = string.split('.')
const res = paths.reduce((acc, curr) => [...acc, `${acc[acc.length-1] ? acc[acc.length-1] + '.' : ''}${curr}`], [])
console.log(res)
You could get the position of the dots and slice the array.
const
string = 'path1.path2.path3',
result = [];
let p = string.indexOf('.');
while (p !== -1) {
result.push(string.slice(0, p));
p = string.indexOf('.', p + 1);
}
result.push(string);
console.log(result);

How to split pipe separated string into array of object

I have pipe separated string (sshshhs , 1) | (ee23es , 1) , I want to split and make an array of object . Result must be like [ {name:sshshhs,value:1},{name:ee23es,value:2} ]. I am new to JavaScript could someone please help me .
Thanks
Check out this code snippet
let myString = "(sshshhs , 1) | (ee23es , 1)";
// extract only the elements
let stringList = myString .split(/\) \| \(|\(|\)/);
// remove first and last empty elements, due to regex
stringList = stringList.slice(1,-1);
//split each element into an object
let objList = stringList.map(s => {
const [name, value] = s.split(',').map(el => el.trim());
return { name, value };
})
In this way with one regex you get rid of pipe and parenthesis. Then with a map you extract the name and value from each element.
You have multiple ways to transform your string into an array of object
One of them could be to split multiple times and use reduce to make the object
"(sshshhs , 1) | (ee23es , 1)"
.split('|') // here we first split with the principal key
.map(e => {
return [e.replace(/\(|\)/g, '')] // we create an object of your values to reduce it
.reduce((result, token) => {
const [name, value] = token.split(',').map(e => e.trim()); // we get the key/values by splitting it (and trimming it by the same time)
return {name, value}; // we then return the finded name and value
}, {})
})
This is definitly not the most efficient way to do it, but it will help you understand the mechanics behind split and reduce and help you create your own solution

Match all possible combinations of substring in array

Assuming I have an input string like "auto encoder" and array of strings
const arr = ['autoencoder', 'auto-encoder', 'autoencoder']
I want the input string to match with all three in array.
I created regex
arr.some(word => word.match(/^[a-zA-Z]+(?:(?:\s[a-zA-Z]+)+|(?:\-[a-zA-Z]+)|(?:[a-zA-Z]+))$/))
but seems it doesn't work as if I test it against an array with a single element like ['auto-encoder'] it returns nothing.
How can I achieve desired matching?
function isIncluded(str, arr) {
str = str.replace(/\W/g, '');
return arr.some(e => (e.replace(/\W/g, '') === str));
}
What about replacing special characters (non-word characters) and comparing with the array?
const arr = ['auto encoder', 'autoencoder'];
const fn = (s, a) => a.includes(s.replace(/\W/g, ''));
console.log(fn('auto-encoder', arr));
console.log(fn('a u t o e n c o d e r', arr));
console.log(fn('random', arr));
I think your input is gonna be a string, not an array of strings. You have already the regex, you just need to define a function around it:
function f(word) {
return word.match(/^[a-zA-Z]+(?:(?:\s[a-zA-Z]+)+|(?:\-[a-zA-Z]+)|(?:[a-zA-Z]+))$/);
}
And if you rinput is gonna be an array you can use various array methods:
If you want a boolean answer if some elements match
function f(arr) {
return arr.some(word => word.match(/^[a-zA-Z]+(?:(?:\s[a-zA-Z]+)+|(?:\-[a-zA-Z]+)|(?:[a-zA-Z]+))$/));
}
If you want to know if all elements match use every instead of some
You have other options. For having the array of the matches use filter:
function f(arr) {
return arr.filter(word => word.match(/^[a-zA-Z]+(?:(?:\s[a-zA-Z]+)+|(?:\-[a-zA-Z]+)|(?:[a-zA-Z]+))$/));
}
You could answer your function(s) according to what you want to achieve with each one.

How to filter a string that represents objects

Unfortunately, my web services response is returning me a String like this:
{"valueStr":"Single"|"valueId":"2019"}
{"valueStr":"Married"|"valueId":"2019"}
{"valueStr":"Divorced"|"valueId":"2020"}
{"valueStr":"Widowed"|"valueId":"2020"}
I need to filter out those with the valueId. For example, all the 2019 or all the 2020.
The response isn't JSON so I can't parse it, and it's not delimited correctly. So I'm stuck trying something unelegant like this:
function parseItemByYear(item){
// replace all | with ,
var modifiedObj = item.replace(/\|/g, ',');
// split into array
var newArr = modifiedObj.split('}');
// remove all
var newestArr = newArr.map(function(item){item.replace(/^\{/g,'')});
// JSON.parse the object
// var lovObj = JSON.parse(modifiedFilingStatusObj);
// capture the current tax year
// replace , with |
// rebuild the object
// return the filtered object
return newestArr;
}
But I'm failing where I'm trying to set newestArr. My RegEx is wrong. Is my approach too complicated? Is there an easier way that I'm not seeing? Thanks for any tips.
I think this is simple and will do the trick.
// Assuming it's single or multiline string
let response = `{"valueStr":"Single"|"valueId":"2019"}
{"valueStr":"Married"|"valueId":"2019"}
{"valueStr":"Divorced"|"valueId":"2020"}
{"valueStr":"Widowed"|"valueId":"2020"}`;
function parseItemByYear(response) {
// Replace '|' with ','
response = response.replace(/\|/g, ',');
// Replace '}{' with any whitespace in between to '},{'
response = response.replace(/}\s?{/g, '},{');
// Make it an array
let arr = JSON.parse(`[${response}]`);
// Return an array of valueId attribute of all array elements
return arr.map(item => item.valueId);
}
console.log(parseItemByYear(response));
You should have split it by new line \n and the just use JSON.parse as it resembles JSON enough to be parsed.
const response = `{"valueStr":"Single"|"valueId":"2019"}{"valueStr":"Married"|"valueId":"2019"}{"valueStr":"Divorced"|"valueId":"2020"}{"valueStr":"Widowed"|"valueId":"2020"}`;
function parseItemByYear(response){
// replace all `|` with `,`
response = response.replace(/\|/g, ',');
// replace all `}` with `}**BREAK**`
response = response.replace(/\}/g, '}**BREAK**');
// split into array
const newArr = response.split('**BREAK**');
// Remove last emenet added by regexp
newArr.pop()
try {
return newArr.map(item => JSON.parse(item)/*.valueId*/);
} catch(e) {
return new Error('Coud not be parsed');
}
}
console.log(parseItemByYear(response));
This is a list of data handling to get only valueID.
This code is only here to work without JSON (in case of need) but you should consider use standardised format.
const str = `{"valueStr":"Single"|"valueId":"2019"}
{"valueStr":"Married"|"valueId":"2019"}
{"valueStr":"Divorced"|"valueId":"2020"}
{"valueStr":"Widowed"|"valueId":"2020"}`
const results = str.replace(/[\{\}\"]/g, "").split("\n").map(el => el.split("|").map(kv => kv.split(':')).filter(arr => arr[0] === 'valueId')).map(el => el[0][1])
console.log(results)
It's always better to use valid stanrd like JSON, use this toJSON function to transform your string into a valid JSON object easier to use.
const str = `{"valueStr":"Single"|"valueId":"2019"}
{"valueStr":"Married"|"valueId":"2019"}
{"valueStr":"Divorced"|"valueId":"2020"}
{"valueStr":"Widowed"|"valueId":"2020"}`
const toJSON = (str) => JSON.parse('[' + (str
.replace(/(?:\r\n|\r|\n)/g, '')
.replace(/\|/g, ",")
.replace(/}{/g, "},{")) + ']')
console.log(toJSON(str))
console.log(toJSON(str).map(el => el.valueId))

Chaining array and string methods in javascript

I try to chain some array and string methods but it doesn't work. It'd be great if anyone could explain to me why a function such as this doesn't work:
const scream = text => text.split('').push('!').join('').toUpperCase()
You could use Array#concat to return an array with another value instead of Array#push, which returns the new length, but is not part of a fluent interface for a later joining (which needs an array).
const scream = text => text.split('').concat('!').join('').toUpperCase();
console.log(scream('hi'));
Push doesn't return the array. Here's an example that demonstrates what's happening with push, and shows another way to do it:
const scream = text => text.split('').push('!').join('').toUpperCase()
const test = ['a', 'b', 'c'];
const result = test.push('!')
console.log(result)
const newScream = text => [
...text,
'!'
].join('').toUpperCase()
newScream('hello')
console.log(newScream('hello'))
If you want to add 1 ! at the end:
const scream = text => text.split('').concat('!').join('').toUpperCase();
If you want to add it after each letter:
const scream = text => text.split('').map(e => e + '!').join('').toUpperCase();
The push don't return array, so join is not called on array in your case.
If you want to add character/string at the end of string use concat(<ch>) function. If you want to change case to upper then use toUpperCase() function.
Or
Simply you can use + operator to concat two strings and append ! to it.
var str = "Hello World";
var res = str.toUpperCase().concat("!");
var result = (str + '!').toUpperCase();
console.log(res);
console.log(result);

Categories

Resources