Camelcase string to normal string - javascript

How to change NoOfSAP => No Of SAP? I have trying the replace method but it says undefined.
function unCamlelCase(result) {
return result.key.replace(/([^A-Z]*)([A-Z]*)([A-Z])([^A-Z]*)/g, '$1 $2 $3$4')
.replace(/ +/g, ' ');
};
How can I change the result key values camel case to normal string?
if (exactMatch) {
const { ...response } = json[0];
const result = Object.keys(response).reduce((acc, key) => {let newKey = key.charAt(0).toUpperCase() + key.slice(1);
return acc;
}, {});

You could use the following expression with a few helper methods to clean up the output:
"NoOfSAP".split(/([A-Z][a-z]+)/).filter(Boolean).join(' ');
This will match all upper case letters followed by one or more lower-case letters and split each chunk into an array. .filter(Boolean) is then used to remove any empty strings in the array and .join is then used to add spaces between the strings in the array.
See example below:
const getWords = wrd =>
wrd.split(/([A-Z][a-z]+)/).filter(Boolean).join(' ');
console.log(getWords("NoOfSAP")); // No Of SAP
console.log(getWords("ThisIsAWord")); // This Is A Word (notice how it will split individual letters such as A)
console.log(getWords("IAmAHuman")); // I Am A Human
console.log(getWords("JSIsGreat")); // JS Is Great (notice how it understands JS and Is are two seperate words and doesn't give JSI s Great)
As per your question about changing the keys in your object to the "uncamelcased" keys you can use .map with Object.keys to generate your result:
const getWords = wrd =>
wrd.split(/([A-Z][a-z]+)/).filter(Boolean).join(' ');
const obj = {
"NoOfSAP": 1,
"NoOfBUN": 2,
"NoOfBRE": 3,
"NoOfPEA": 4
}
const result = Object.keys(obj).map(getWords);
console.log(result);

You can go that way:
const camelToWords = (camelCaseWord) => camelCaseWord
.replace(/([A-Z]+)/g, " $1")
.replace(/([A-Z][a-z])/g, "$1");
There is also possibility to use existing libraries like lodash:
const _ = require('lodash');
console.log(_.startCase('abcDef'));
// result: Abc Def

Related

Replace certain values in a string based on a mapping - JS

I have a string with words followed by a colon. I need to replace the colon words in that string with values from an object. I was able to extract out the colon words but not sure on the best way to replace it in the string.
This is what I have:
const string = 'This is :state :buttonName by :name';
const buttonName = 'button link';
const data = {
state: 'Alabama',
name: 'Arun'
}
const res = string.match(/:[a-zA-Z]+/g).map(i => i.replace(':', ''))
console.log(res)
// This is Alabama button link by Arun
End result should be
This is Alabama button link by Arun
Please advice.
First of all, you need to move const buttonName = 'button link'; to the array.
You need to use String#replace, but also you need to capture the part of the regex after : and actually use the Group #1 value as key to get the right data value.
Besides, you need to check if the extracted key is inside the dictionary to avoid issues.
You can use
const string = 'This is :state :buttonName by :name';
const data = {
buttonName: 'button link',
state: 'Alabama',
name: 'Arun'
}
const res = string.replace(/:([a-zA-Z]+)/g, (m, i) => i in data ? data[i] : m)
console.log(res)
You can split the string and then call array map to replace words and the join to final string
const str= 'This is :state :buttonName by :name';
str.split(' ').map(a => {
if(a.startsWith(":"))
return data[a.replace(":","")];
return a;
}).join(' ');
If you've already stripped the ":" from the string you can just iterate your object keys and replace them with the respective values.
...
const res = string.match(/:[a-zA-Z]+/g).map(i => i.replace(':', ''))
for (const [key, value] of Object.entries(data)) {
res = res.replaceAll(key, value);
}
Wiktor's answer is good. But if it needs to replace the global variable as well, we can write the code as belows.
const res = string.replace(/:([a-zA-Z_]+)/g, (m, i) => data[i] ?? eval(i) ?? m);
console.log(res)
This code didn't do exception handling yet. It should be in consideration. So we can define a replacer function handling exception
const replacer = (m, i) => {
try {
return data[i] ?? eval(i);
} catch {
return m;
}
}
const res = string.replace(/:([a-zA-Z_]+)/g, replacer);

How to separate a substring in a complicate string in JavaScript?

For example:
str = "A=sample_text1; B=sample_text2; C=sample_text3;";
How can I get the text after "A=", which is "sample_text1" out ? (the length of sample_text1 can be very long, so str.substring won't work here)
Looks like your string has a structure where there are multiple fields where each field is represented as:
[KEY]=[VALUE];
You can use common string and array methods like split and map to extract what you need. In this case looks like you want the value of the first field:
const str = 'A=sample_text1; B=sample_text2; C=sample_text3;';
const result = str.split(';').map(s => s.split('=').pop().trim()).shift();
console.log(result); //=> 'sample_text1'
https://regexr.com is very useful for creating and testing regex.
const match = "A=sample_text1; B=sample_text2; C=sample_text3;".match(/A=([^;]*)/);
let value = match !== null ? match[1] : undefined;
Would allow you to get the value of A in this case
You could use a regular expression to capture every group surrounded by a = and a ;:
const str = "A=sample_text1; B=sample_text2; C=sample_text3;";
const regexp = "=(.*?);";
const values = [...str.matchAll(regexp)];
const aValue = values[0][1];
console.log(aValue);
It might be an overkill, but to easily access to all the keys / values, you could use Object.fromEntries:
let str = "A=sample_text1; B=sample_text2; C=sample_text3;";
let values = Object.fromEntries(
str
// Split all the pairs
.split(";")
// Remove the last empty element
.slice(0,-1)
// map to a [key, value] array to pass to Object.fromEntries
.map(i => i.split("=").map(j => j.trim())));
// get a value using a key
console.log(values["A"]) // sample_text1
// check if a key is present
console.log("C" in values) // true
console.log("D" in values) // false
It looks more longer than it is due the comments and the console logs, it can fit in one line.
Notice that this is assume of course that neither the character = or ; can be part of the key or the value.

How can I tell whether or not an element inside an array is a number or a word (all elements in quotes)

Background information: I have an array
this.someArray = ["Word", "123", "456"]
Where this.someArray is dynamically written (the array elements are not hardcoded)
I need to convert all items that are numbers into numbers (yes I realise that this might not make sense, essentially this is the result I want - where the numbers don't have quotes but leave the words as they are):
["Word", 123, 456]
So the steps I've thought in terms of how to achieve this:
Find out whether each element in the array is a word or number
To achieve this I have:
isNumber(number) {
return !isNaN(parseFloat(number)) && !isNaN(number-0)
}
Use a for each loop to test whether each element is a word or number
this.someArray.forEach(element => {
this.isNumber(element)
});
Write an if statement (if the element in this.someArray is a number then remove the quotes from that element)
However I'm unsure of whether step 2 is actually the correct thing to do and I'm unsure of how to write step 3
Is there a way to accomplish this?
Further info:
This is what the dynamically generated array looks like:
This is the code:
this.someArray = this.biggerArray.map((n) => {
const data = [];
for (var key of Object.keys(n)) {
data.push(n[key].data);
}
return data;
});
I think a plain .map would be easier - check if the string is composed of all digits with a regular expression, and if so, call Number on it:
const arr = ["Word", "123", "456"];
const newArr = arr.map(
str => /^\d+$/.test(str) ? Number(str) : str
);
console.log(newArr);
^\d+$ means:
^ - start of string
\d+ - one or more digits
$ - end of string
If the numbers might contain decimals, then add an optional group for the decimal portion:
const arr = ["Word", "123", "456", '12.45'];
const newArr = arr.map(
str => /^\d+(?:\.\d+)?$/.test(str) ? Number(str) : str
);
console.log(newArr);
For the array of ['Process', '1287'], it still works as expected:
const arr = ['Process', '1287'];
const newArr = arr.map(
str => /^\d+(?:\.\d+)?$/.test(str) ? Number(str) : str
);
console.log(newArr);
This approach also works for decimals within quotes.
for (let i in someArray) {
if (parseFloat(someArray[i])) {
someArray[i] = parseFloat(someArray[i]);
}
}
This is a shorter way of doing it.
for (let i in someArray) {
parseFloat(someArray[i]) && (someArray[i] = parseFloat(someArray[i]));
}

Using trim more than once in an array JS

I have a snippet of code where I am trying to parse a longer string with special characters into an array with no spaces or special characters.
input: name: this is some stuff, name2: this is more stuff
desired output: [name,this is some stuff,name2,this is more stuff]
current output: z.trim isn't a function
function parseOrder(custOrder) {
const custOrderArr = custOrder.split(',');
const trimedArr = custOrderArr.map((x) => x.trim());
const numberArr = trimedArr.map((y) => y.split(':'));
const processArr = numberArr.map((z) => z.trim());
console.log(processArr);
}
Why does trim work the first time and not the second?
You can not trim an array. But you could map the array and trim the values.
This result features Array#flatMap for preventing arrays with pairs.
function parseOrder(custOrder) {
return custOrder
.split(',')
.flatMap(y => y.split(':').map(x => x.trim()));
}
var input = 'name: this is some stuff, name2: this is more stuff ';
console.log(parseOrder(input));
Try to split by two signs, then trim your elements:
const result = str.split(/[\:,]+/).map(s => s.trim());
An example:
let str = 'test: It is me, test2: it is me 2 ';
console.log(str.split(/[\:,]+/).map(s => s.trim()));

How to check if 2 strings separated by delimiters have matching word

Trying to check if 2 strings have matching word return true.
let 1st_string = chin, kore, span;
let 2nd_string = chin eng kore zulu
1st_string.split(',').indexOf(2nd_string) > -1
I tried above code but always returns false. I need to return true as 2_nd string contains 2 matching words from 1st_string.
Solved the names and values of the variables you can do the following
let first_string = 'chin, kore, span';
let second_string = 'chin eng kore zulu';
const array1 = first_string.split(',').map(string => string.trim());
const array2 = second_string.split(' ');
function exist(list1, list2) {
for (const element of list1) {
if (list2.includes(element)) {
return true;
}
}
return false;
}
const result = exist(array1, array2);
console.log(result);
1st_string is not a valid variable name
split the first string and use Array.some() to see if the second string has any of the words in the resulting array :
let string_1 = 'chin, kore, span';
let string_2 = 'chin eng kore zulu';
const check = (str1, str2) => {
return str1.split(',').some(word => str2.includes(word));
}
console.log(check(string_1, string_2))
I think your second string will also contain a comma in between the words if yes then it is easy to achieve.
you can split the string 1 and 2 with a comma as delimiter like this
let firstString = 1st_string.split(',');
let secondString = 2nd_string.split(',');
after doing you will get the firstString and secondString variable as array then you can iterate the first array and check for duplicate using includes methods
for (let i in firstString) {
if(secondString.includes(firstString[i])){
//you can do whatever you want after finding duplicate here;
}
}

Categories