How can I count characters in an JavaScript array? - javascript

I need to count the characters from a to z in an array.
For example I have an array like this:
["max","mona"]
The desired result would be something like this:
a=2, m=2, n=1, o=1, x=1
It would be great, if anyone could help me :)

You can use two forEach loops and return object
var ar = ["max", "mona"], o = {}
ar.forEach(function(w) {
w.split('').forEach(function(e) {
return o[e] = (o[e] || 0) + 1;
});
});
console.log(o)
Or with ES6 you can use arrow function
var ar = ["max","mona"], o = {}
ar.forEach(w => w.split('').forEach(e => o[e] = (o[e] || 0)+1));
console.log(o)
As #Alex.S suggested you can first use join() to return string, then split() to return array and then you can also use reduce() and return object.
var ar = ["max", "mona"];
var result = ar.join('').split('').reduce(function(o, e) {
return o[e] = (o[e] || 0) + 1, o
}, {});
console.log(result)

You can use just one forEach loop and return object
var ar = [ "bonjour", "coucou"], map = {};
ar.join("").split("").forEach(e => map[e] = (map[e] || 0)+1);
console.log(map);
Live Demo
https://repl.it/C17p

I would do it like this;
var a = ["max","mona"],
charCount = a.reduce((p,w) => w.split("").reduce((t,c) => (t[c] ? t[c]++: t[c] = 1,t),p),{});
console.log(charCount);

public static void main (String[] args) throws java.lang.Exception
{
String[] original = {"The","Quick","Brown","Fox","Jumps","Over","The","Lazy","Dog"};
String singleString ="";
for(String str : original )
{
singleString += str;
}
System.out.println(singleString);
char[] chars = singleString.toLowerCase().toCharArray();
Arrays.sort(chars);
String result="";
for(int i=0;i<chars.length;)
{
result += chars[i]+"=";
int count=0;
do {
count++;
i++;
} while (i<chars.length-1 && chars[i-1]==chars[i]);
result += Integer.toString(count)+",";
}
System.out.println(result.substring(0,result.length()-1));
}

The solution using Array.join, Array.sort and String.split functions:
var arr = ["max","mona"],
counts = {};
arr = arr.join("").split(""); // transforms the initial array into array of single characters
arr.sort();
arr.forEach((v) => (counts[v] = (counts[v])? ++counts[v] : 1));
console.log(counts); // {a: 2, m: 2, n: 1, o: 1, x: 1}

Try this:
var words = ['max', 'mona'],
output = {};
words.forEach(function(word){
for(i=0; i < word.split('').length; i++){
if(output[word[i]])
output[word[i]] += 1;
else{
output[word[i]] = 1;
}
}
});
ps: sorry for the code not being formatted, I'm still getting used to the editor =)

Related

Take a string , evaluate it and find if there is a number and repeat part of string that number of times?

I was writing code and came into this problem,
You have a specific string which is in this form:
d ae2 n s
now we have to decode this in a specific way,
Split it into different parts by spaces to make an array like ["d","ae2","n","s"]
Evaluate each element of the array and find out if there is a number in it.
If there is a number then repeat the string the number of times.
Add it into the array and continue.
So the output array should be
["d","ae","ae","n","s"]
I have already tried a lot but got nothing
I have used this code earlier but it ends on the second string:
var str = "d ae2 n s"
var res = str.split(" ");
alert(res.length);
for(var x = 0; x < res.length; x++ ){
var std = res[x];
var fun = checkNum(std);
if(fun === true){
var numbers = str.match(/\d+/g).map(Number);
var index = res.indexOf(std);
var result = std.replace(/[0-9]/g, '');
var res2 = result.repeat(numbers);
res[index] = res2;
}
else{
continue;
}
for(var i = 0; i < res.length; i++ ){
console.log(res[x]);
}
}
function checkNum(t){
return /\d/.test(t);
}
// I am a terible coder :/
expected input : d ae2 n s
expected output : ["d","ae","ae","n","s"]
Using fill() and flatMap() methods and
regex replace
/[^0-9]/ - all non numerical chars
/[0-9]/ - all numerical chars
var str = 'd ae2 n s'
var res = str
.split(' ')
.flatMap(i =>
Array(+i.replace(/[^0-9]/g, '') || 1)
.fill(i.replace(/[0-9]/g, ''))
)
console.log(res)
You can simply loop over your array and populate an other array that will hold your result after checking for a number :
const results = [];
"d ae2 n s".split(' ').forEach(token => {
const match = token.match(/\d+/);
if (match) {
const newStr = token.split(/\d/)[0];
for (let i = 0; i < match[0]; i++) {
results.push(newStr);
}
} else {
results.push(token)
}
})
console.log(results);
You can check Seblor's answer for optimized logic. I have modified your code so that it will be easy for you to understand where you went wrong while doing this. I have added comments to your code where I have changed things:
var str = "d ae2 n s"
var res = str.split(" ");
// create a variable to store the output.
var output = [];
for(var x = 0; x < res.length; x++ ){
var std = res[x];
var fun = checkNum(std);
if(fun === true){
// map returns an array, so take the first element, it will be your number.
var numbers = str.match(/\d+/g).map(Number)[0];
var index = res.indexOf(std);
var result = std.replace(/[0-9]/g, '');
// instead of doing the repeat and updating the current index,
// push the result, i.e. the current string to be repeated "numbers" times into
// the output array.
for (var i = 0; i < numbers; i++) {
output.push(result)
}
}
else{
// if does not contain any number, push the current item to ouput
output.push (std);
continue;
}
}
function checkNum(t){
return /\d/.test(t);
}
console.log(output);
You can do:
const str1 = 'd ae2 n s';
const str2 = 'e d aefg4 m n s';
const regex = /\d+/;
const getResult = input => input.split(' ').reduce((a, c) => {
const n = c.match(regex);
return n
? [...a.concat(c.replace(n, ' ').repeat(n).trim().split(' '))]
: [...a, c];
}, []);
console.log(getResult(str1));
console.log(getResult(str2));
you can use the Array prototype reduce and filter
const input = 'd ae2 n s';
const output = input.split(' ').reduce((memory, current) => {
const numberIndex = current.split('').findIndex(c => !isNaN(c));
const newCurrent = current.split('').filter((_, index) => index !== numberIndex).join('');
if(numberIndex !== -1) {
for(let i = 0; i < parseInt(current[numberIndex]); i++) {
memory.push(newCurrent);
}
} else {
memory.push(current);
}
return memory;
}, []);
console.log(output);
Hope this helped
You can try with following:
let str = "d ae2 n s"
let split = str.split(" ")
let rx = new RegExp("[0-9]")
let res = [];
split.forEach(s => {
if(rx.exec(s) !== null) {
let rxResult = rx.exec(s)
let count = rxResult[0];
let matchIdx = rxResult[1];
for(let i = 0; i < count; i++) {
res.push(s.replace(count, ""))
}
} else {
res.push(s);
}
})

How can i access this object key in this conditional?

Write a function countWords that, when given a string as an argument, returns an object where keys are the words in the string, and values are the number of occurrences of that word within the string:
function countWords(string){
string = string.split(" ");
var newObj = {};
for(var i = 0 ; i === newObj.string ; i++){
if(newObj['i'] === newObj[string]){
newObj[string[i]] = i ;
}
}
return newObj;
}
countWords("hello hello"); // => {"hello": 2}
countWords("Hello hello"); // => {"Hello": 1, "hello": 1}
countWords("The quick brown"); // => {"The": 1, "quick": 1, "brown": 1}
I realized since you do not need to count the index of the split string, you have to change the conditions from i < string.length to i === key value of of the objects. Why can't I access the strings with newObj.string?
You could do this with reduce() instead of for loop.
function countWords(string) {
return string.split(' ').reduce(function(r, e) {
r[e] = (r[e] || 0) + 1;
return r;
}, {})
}
console.log(countWords("hello hello"))
console.log(countWords("Hello hello"))
console.log(countWords("The quick brown"))
With for loop your code could go like this.
function countWords(string) {
var string = string.split(" ");
var newObj = {};
for (var i = 0; i < string.length; i++) {
newObj[string[i]] = (newObj[string[i]] || 0) + 1
}
return newObj;
}
console.log(countWords("hello hello"));
console.log(countWords("Hello hello"));
console.log(countWords("The quick brown"));
function countWords(string){
return string
.split(" ")
.reduce((acc, curr) => {
if (curr in acc) {
acc[curr]++
} else {
acc[curr] = 1
}
return acc
}, {})
}
console.log(countWords("hello hello"));
console.log(countWords("Hello hello"));
console.log(countWords("The quick brown"));
You can do it in the following way by using the hasOwnProperty function to check if a property exists in the JavaScript Object, if it does increment the count and if it doesn't then initialize the count to 1.
function countWords(data) {
var words = data.split(" ");
var item = {};
for (var i = 0; i < words.length; i++) {
var prop = words[i];
item.hasOwnProperty(prop) ? item[prop] ++ : item[prop] = 1;
}
console.log(item);
return item;
}
countWords("hello hello"); // => {"hello": 2}
countWords("Hello hello"); // => {"Hello": 1, "hello": 1}
countWords("The quick brown"); // => {"The": 1, "quick": 1, "brown": 1}
newObj[string[i]] = (newObj[string[i]] || 0) + 1
according to my understanding this statement is used to check for duplicity
suppose you crated an empty object and then stored the key value pair in it by using this statement "(newObj[string[i]] || 0) + 1" you are checking if the default value of the key is zero if its zero you then increment its value by 1 if there are multiple value for the same key by doing this you can get the unique value in the array
Example
const uniqueValues = arr => {
let newObj = {}
for (let val of arr){
newObj[val] = [newObj || 0] + 1;
}
return (Object.keys(newObj).length);
}
uniqueValues([1,1,1,1,1,2]);

Remove duplicate in a string - javascript

I have a string in javascript where there are a lot of duplicates. For example I have:
var x = "Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Double,Double,Double"
What can I do to delete duplicates and to get for example x="Int32,Double"?
With Set and Array.from this is pretty easy:
Array.from(new Set(x.split(','))).toString()
var x = "Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Double,Double,Double"
x = Array.from(new Set(x.split(','))).toString();
document.write(x);
If you have to support current browsers, you can split the array and then filter it
var x = "Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Double,Double,Double";
var arr = x.split(',');
x = arr.filter(function(value, index, self) {
return self.indexOf(value) === index;
}).join(',');
document.body.innerHTML = x;
Use new js syntax remove Dupicate from a string.
String.prototype.removeDuplicate = Function() {
const set = new Set(this.split(','))
return [...set].join(',')
}
x.removeDuplicate()
function myFunction(str) {
var result = "";
var freq = {};
for(i=0;i<str.length;i++){
let char = str[i];
if(freq[char]) {
freq[char]++;
} else {
freq[char] =1
result = result+char;
}
}
return result;
}
That is a more readable and better parameterized solution:
var x = "Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Double,Double,Double"
var removeDup = [...new Set(x.split(","))].join(",");
//result "Int32,Double"
Check This out -
removeDuplicates() function takes a string as an argument and then the string split function which is an inbuilt function splits it into an array of single characters. Then the arr2 array which is empty at beginning, a forEach loop checks for every element in the arr2 - if the arr2 has the element it will not push the character in it, otherwise it will push. So the final array returned is with unique elements. Finally we join the array with the join() method to make it a string.
const removeDuplicates = (str) => {
const arr = str.split("");
const arr2 = [];
arr.forEach((el, i) => {
if (!arr2.includes(el)) {
arr2.push(el);
}
});
return arr2.join("").replace(",", "").replace("", " ");
};
console.log(removeDuplicates( "Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Double,Double,Double"));
Its simple just remove duplicates in string using new Set and join them.
var x = "Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Double,Double,Double";
console.log([...new Set(x)].join(""));
function removeDups(s) {
let charArray = s.split("");
for (let i = 0; i < charArray.length; i++) {
for (let j = i + 1; j < charArray.length; j++)
if (charArray[i] == charArray[j]) {
charArray.splice(j, 1);
j--;
}
}
return charArray.join("");
}
console.log(removeDups("Int32,Int32,Int32,InInt32,Int32,Double,Double,Double"));
You can use Set()
const result = Array.from(new Set(x)).join('')
var x = "Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Double,Double,Double"
const result = Array.from(new Set(x)).join('')
console.log(result)
you can use the replaceAll function:
let str = "/Courses/"
let newStr = str.replaceAll('/', '')
console.log(newStr) // result -> Courses
function removeDuplicate(x)
{
var a = x.split(',');
var x2 = [];
for (var i in a)
if(x2.indexOf(a[i]) == -1) x2.push(a[i])
return x2.join(',');
}
const str = "Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Int32,Double,Double,Double";
const usingSpread = [...str]
const duplicatesRemove = [...new Set(usingSpread)]
const string = duplicatesRemove.join("")
console.log("After removing duplicates: " + string)
STEPS
convert string to character array using spread operator
new Set will implicitly remove duplicate character
convert character array to string using join("") method

How to convert an x-www-form-urlencoded string to JSON?

Exampple of application/x-www-form-urlencoded string
CorrelationId=1&PickedNumbers%5B%5D=1&PickedNumbers%5B%5D=2&PickedNumbers%5B%5D=3&PickedNumbers%5B%5D=4
Into JSON
var gamePlayData = {
CorrelationId: gameId,
PickedNumbers: ["1","2","3","4"]
};
This is a core module of Node.js now: https://nodejs.org/api/querystring.html#querystring_querystring_parse_str_sep_eq_options
var qs = require('querystring')
var json = qs.parse('why=not&sad=salad')
// { why: 'not', sad: 'salad' }
Works with encoded characters too:
var json2 = qs.parse('http%3A%2F%2Fexample.com&sad=salad')
// { url: 'http://example.com', sad: 'salad' }
I've been dealing with this recently: I had to parse data that could contain objects nested up to 5 levels deep. I needed the code to be able to deal with both rather complex data, but not fail to decode a URI as simple as id=213.
I spent quite some time on google, trying to find a (semi-)elegant solution to this problem, and this question kept showing up. Since it gets 1 view/day (give or take) I've decided to post my solution here, hope it helps someone out:
function form2Json(str)
{
"use strict";
var obj,i,pt,keys,j,ev;
if (typeof form2Json.br !== 'function')
{
form2Json.br = function(repl)
{
if (repl.indexOf(']') !== -1)
{
return repl.replace(/\](.+?)(,|$)/g,function($1,$2,$3)
{
return form2Json.br($2+'}'+$3);
});
}
return repl;
};
}
str = '{"'+(str.indexOf('%') !== -1 ? decodeURI(str) : str)+'"}';
obj = str.replace(/\=/g,'":"').replace(/&/g,'","').replace(/\[/g,'":{"');
obj = JSON.parse(obj.replace(/\](.+?)(,|$)/g,function($1,$2,$3){ return form2Json.br($2+'}'+$3);}));
pt = ('&'+str).replace(/(\[|\]|\=)/g,'"$1"').replace(/\]"+/g,']').replace(/&([^\[\=]+?)(\[|\=)/g,'"&["$1]$2');
pt = (pt + '"').replace(/^"&/,'').split('&');
for (i=0;i<pt.length;i++)
{
ev = obj;
keys = pt[i].match(/(?!:(\["))([^"]+?)(?=("\]))/g);
for (j=0;j<keys.length;j++)
{
if (!ev.hasOwnProperty(keys[j]))
{
if (keys.length > (j + 1))
{
ev[keys[j]] = {};
}
else
{
ev[keys[j]] = pt[i].split('=')[1].replace(/"/g,'');
break;
}
}
ev = ev[keys[j]];
}
}
return obj;
}
I've tested it, with data like the string below (4 levels deep):
str = "id=007&name[first]=james&name[last]=bond&name[title]=agent&personalia[occupation]=spy&personalia[strength]=women&personalia[weakness]=women&tools[weapons][close][silent]=garrot&tools[weapons][medium][silent]=pistol_supressed&tools[weapons][medium][loud]=smg&tools[weapons][far][silent]=sniper&tools[movement][slow]=foot&tools[movement][far]=DBS";
Which neatly returns an object, that, when passed through JSON.stringify comes out like this:
{"id":"007","name":{"title":"agent","first":"james","last":"bond"},"personalia":{"weakness":"women","occupation":"spy","strength":"women"},"tools":{"movement":{"far":"DBS","slow":"foot"},"weapons":{"close":{"silent":"garrot"},"medium":{"silent":"pistol_supressed","loud":"smg"},"far":{"silent":"sniper"}}}}
It passes a JSlint check, when ignoring white space, . and [^...] and accepting ++. All in all, I'd consider that to be acceptable.
You can use qs if you're using node, or browserify.
var qs = require('qs')
var encodedString = "CorrelationId=1&PickedNumbers%5B%5D=1&PickedNumbers%5B%5D=2&PickedNumbers%5B%5D=3&PickedNumbers%5B%5D=4"
console.log(qs.parse(encodedString))
// { CorrelationId: '1', PickedNumbers: [ '1', '2', '3', '4' ] }
the following code should do the trick:
var str = 'CorrelationId=1&PickedNumbers%5B%5D=1&PickedNumbers%5B%5D=2&PickedNumbers%5B%5D=3&PickedNumbers%5B%5D=4';
var keyValuePairs = str.split('&');
var json = {};
for(var i=0,len = keyValuePairs.length,tmp,key,value;i <len;i++) {
tmp = keyValuePairs[i].split('=');
key = decodeURIComponent(tmp[0]);
value = decodeURIComponent(tmp[1]);
if(key.search(/\[\]$/) != -1) {
tmp = key.replace(/\[\]$/,'');
json[tmp] = json[tmp] || [];
json[tmp].push(value);
}
else {
json[key] = value;
}
}
Updated answer for 2022, works both in the browser and in node.
Use URLSearchParams class.
Note: The param name PickedNumbers%5B%5D will turn to be the literal string PickedNumbers[]. You don't need to encode the brackets in order to make it an array
const paramsStr = 'CorrelationId=1&PickedNumbers%5B%5D=1&PickedNumbers%5B%5D=2&PickedNumbers%5B%5D=3&PickedNumbers%5B%5D=4';
const params = new URLSearchParams(paramsStr);
//access a specific param
console.log(params.get('PickedNumbers[]')); // '4'
console.log(params.getAll('PickedNumbers[]')); // ['1','2','3','4']
const o = Object.fromEntries(Array.from(params.keys()).map(k => [k, params.getAll(k).length===1 ? params.get(k) : params.getAll(k)]));
console.log(JSON.stringify(o)); //full object
Here's a pure-JavaScript way to do it. JavaScript frameworks might also help you out with this. EDIT: Just for kicks, I threw in dictionary parsing, too. See the 2nd example.
function decodeFormParams(params) {
var pairs = params.split('&'),
result = {};
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('='),
key = decodeURIComponent(pair[0]),
value = decodeURIComponent(pair[1]),
isArray = /\[\]$/.test(key),
dictMatch = key.match(/^(.+)\[([^\]]+)\]$/);
if (dictMatch) {
key = dictMatch[1];
var subkey = dictMatch[2];
result[key] = result[key] || {};
result[key][subkey] = value;
} else if (isArray) {
key = key.substring(0, key.length-2);
result[key] = result[key] || [];
result[key].push(value);
} else {
result[key] = value;
}
}
return result;
}
decodeFormParams("CorrelationId=1&PickedNumbers%5B%5D=1&PickedNumbers%5B%5D=2&PickedNumbers%5B%5D=3&PickedNumbers%5B%5D=4");
// => {"CorrelationId":"1","PickedNumbers":["1","2","3","4"]}
decodeFormParams("a%5Bb%5D=c&a%5Bd%5D=e");
// => {"a":{"b":"c","d":"e"}}
Try this->
// convert string to object
str = 'a=6&id=99';
var arr = str.split('&');
var obj = {};
for(var i = 0; i < arr.length; i++) {
var bits = arr[i].split('=');
obj[bits[0]] = bits[1];
}
//alert(obj.a);
//alert(obj.id);
// convert object back to string
str = '';
for(key in obj) {
str += key + '=' + obj[key] + '&';
}
str = str.slice(0, str.length - 1);
alert(str);
Or use this (JQuery) http://api.jquery.com/jQuery.param/
A one-liner:
let s = 'a=1&b=2&c=3';
Object.fromEntries(
s.split('&')
.map(s => s.split('='))
.map(pair => pair.map(decodeURIComponent)))
// -> {a: "1", b: "2", c: "3"}
and if you want repeated parameters to be represented as arrays:
let s = 'a=1&b=2&c[]=3&c[]=4&c[]=5&c[]=6';
s
.split('&')
.map(s => s.split('='))
.map(pair => pair.map(decodeURIComponent))
.reduce((memo, [key, value]) => {
if (!(key in memo)) { memo[key] = value; }
else {
if (!(memo[key] instanceof Array))
memo[key] = [memo[key], value];
else
memo[key].push(value);
}
return memo;
}, {})
// -> {"a":"1","b":"2","c[]":["3","4","5","6"]}
You need the opposite of jQuery.param. One of the options is http://benalman.com/code/projects/jquery-bbq/examples/deparam/
var jsonMessage = "{\"".concat(message.replace("&", "\",\"").replace("=", "\":\"")).concat("\"}");
In typescript, works for me:
Use qs.parse to transform in object ParsedQs.
Use as unknow to implicit type unknow and before force convert to string.
Use JSON.parse to convert an string to object.
It was useful to use validations with Joi.
const payload = JSON.parse(JSON.stringify(qs.parse(request.body) as unknown as string));
Payload (cURL):
--data-urlencode 'notification=123-456123' \
--data-urlencode 'test=123456' \
--data-urlencode 'ajieoajeoa=Lorem ipsum'
Result:
{
notification: '123-456123',
test: '123456',
ajieoajeoa: 'Lorem ipsum'
}
public static void Main()
{
string str ="RESULT=0&PNREF=A10AABBF8DF2&RESPMSG=Approved&AUTHCODE=668PNI&PREFPSMSG=No Rules Triggered&POSTFPSMSG=No Rules Triggered";
var sr = str.Replace("&", "=");
string[] sp = sr.Split('=');
var spl = sp.Length;
int n = 1;
var ss = "{";
for (var k = 0; k < spl; k++)
{
if (n % 2 == 0)
{
if (n == spl)
{
ss += '"' + sp[k] + '"';
}
else
{
ss += '"' + sp[k] + '"' + ",";
}
}
else
{
ss += '"' + sp[k] + '"' + ":";
}
n++;
}
ss += "}";
Console.WriteLine(ss);
}

String to object in JS

I have a string as
string = "firstName:name1, lastName:last1";
now I need one object obj such that
obj = {firstName:name1, lastName:last1}
How can I do this in JS?
Actually, the best solution is using JSON:
Documentation
JSON.parse(text[, reviver]);
Examples:
1)
var myobj = JSON.parse('{ "hello":"world" }');
alert(myobj.hello); // 'world'
2)
var myobj = JSON.parse(JSON.stringify({
hello: "world"
});
alert(myobj.hello); // 'world'
3)
Passing a function to JSON
var obj = {
hello: "World",
sayHello: (function() {
console.log("I say Hello!");
}).toString()
};
var myobj = JSON.parse(JSON.stringify(obj));
myobj.sayHello = new Function("return ("+myobj.sayHello+")")();
myobj.sayHello();
Your string looks like a JSON string without the curly braces.
This should work then:
obj = eval('({' + str + '})');
WARNING: this introduces significant security holes such as XSS with untrusted data (data that is entered by the users of your application.)
If I'm understanding correctly:
var properties = string.split(', ');
var obj = {};
properties.forEach(function(property) {
var tup = property.split(':');
obj[tup[0]] = tup[1];
});
I'm assuming that the property name is to the left of the colon and the string value that it takes on is to the right.
Note that Array.forEach is JavaScript 1.6 -- you may want to use a toolkit for maximum compatibility.
This simple way...
var string = "{firstName:'name1', lastName:'last1'}";
eval('var obj='+string);
alert(obj.firstName);
output
name1
Since JSON.parse() method requires the Object keys to be enclosed within quotes for it to work correctly, we would first have to convert the string into a JSON formatted string before calling JSON.parse() method.
var obj = '{ firstName:"John", lastName:"Doe" }';
var jsonStr = obj.replace(/(\w+:)|(\w+ :)/g, function(matchedStr) {
return '"' + matchedStr.substring(0, matchedStr.length - 1) + '":';
});
obj = JSON.parse(jsonStr); //converts to a regular object
console.log(obj.firstName); // expected output: John
console.log(obj.lastName); // expected output: Doe
This would work even if the string has a complex object (like the following) and it would still convert correctly. Just make sure that the string itself is enclosed within single quotes.
var strObj = '{ name:"John Doe", age:33, favorites:{ sports:["hoops", "baseball"], movies:["star wars", "taxi driver"] }}';
var jsonStr = strObj.replace(/(\w+:)|(\w+ :)/g, function(s) {
return '"' + s.substring(0, s.length-1) + '":';
});
var obj = JSON.parse(jsonStr);
console.log(obj.favorites.movies[0]); // expected output: star wars
If you have a string like foo: 1, bar: 2 you can convert it to a valid obj with:
str
.split(',')
.map(x => x.split(':').map(y => y.trim()))
.reduce((a, x) => {
a[x[0]] = x[1];
return a;
}, {});
Thanks to niggler in #javascript for that.
Update with explanations:
const obj = 'foo: 1, bar: 2'
.split(',') // split into ['foo: 1', 'bar: 2']
.map(keyVal => { // go over each keyVal value in that array
return keyVal
.split(':') // split into ['foo', '1'] and on the next loop ['bar', '2']
.map(_ => _.trim()) // loop over each value in each array and make sure it doesn't have trailing whitespace, the _ is irrelavent because i'm too lazy to think of a good var name for this
})
.reduce((accumulator, currentValue) => { // reduce() takes a func and a beginning object, we're making a fresh object
accumulator[currentValue[0]] = currentValue[1]
// accumulator starts at the beginning obj, in our case {}, and "accumulates" values to it
// since reduce() works like map() in the sense it iterates over an array, and it can be chained upon things like map(),
// first time through it would say "okay accumulator, accumulate currentValue[0] (which is 'foo') = currentValue[1] (which is '1')
// so first time reduce runs, it starts with empty object {} and assigns {foo: '1'} to it
// second time through, it "accumulates" {bar: '2'} to it. so now we have {foo: '1', bar: '2'}
return accumulator
}, {}) // when there are no more things in the array to iterate over, it returns the accumulated stuff
console.log(obj)
Confusing MDN docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Demo: http://jsbin.com/hiduhijevu/edit?js,console
Function:
const str2obj = str => {
return str
.split(',')
.map(keyVal => {
return keyVal
.split(':')
.map(_ => _.trim())
})
.reduce((accumulator, currentValue) => {
accumulator[currentValue[0]] = currentValue[1]
return accumulator
}, {})
}
console.log(str2obj('foo: 1, bar: 2')) // see? works!
You need use JSON.parse() for convert String into a Object:
var obj = JSON.parse('{ "firstName":"name1", "lastName": "last1" }');
if you're using JQuery:
var obj = jQuery.parseJSON('{"path":"/img/filename.jpg"}');
console.log(obj.path); // will print /img/filename.jpg
REMEMBER: eval is evil! :D
I implemented a solution in a few lines of code which works quite reliably.
Having an HTML element like this where I want to pass custom options:
<div class="my-element"
data-options="background-color: #dadada; custom-key: custom-value;">
</div>
a function parses the custom options and return an object to use that somewhere:
function readCustomOptions($elem){
var i, len, option, options, optionsObject = {};
options = $elem.data('options');
options = (options || '').replace(/\s/g,'').split(';');
for (i = 0, len = options.length - 1; i < len; i++){
option = options[i].split(':');
optionsObject[option[0]] = option[1];
}
return optionsObject;
}
console.log(readCustomOptions($('.my-element')));
In your case, The short and beautiful code
Object.fromEntries(str.split(',').map(i => i.split(':')));
I'm using JSON5, and it's works pretty well.
The good part is it contains no eval and no new Function, very safe to use.
string = "firstName:name1, lastName:last1";
This will work:
var fields = string.split(', '),
fieldObject = {};
if( typeof fields === 'object') ){
fields.each(function(field) {
var c = property.split(':');
fieldObject[c[0]] = c[1];
});
}
However it's not efficient. What happens when you have something like this:
string = "firstName:name1, lastName:last1, profileUrl:http://localhost/site/profile/1";
split() will split 'http'. So i suggest you use a special delimiter like pipe
string = "firstName|name1, lastName|last1";
var fields = string.split(', '),
fieldObject = {};
if( typeof fields === 'object') ){
fields.each(function(field) {
var c = property.split('|');
fieldObject[c[0]] = c[1];
});
}
const text = '{"name":"John", "age":30, "city":"New York"}';
const myArr = JSON.parse(text);
document.getElementById("demo").innerHTML = myArr.name;
This is universal code , no matter how your input is long but in same schema if there is : separator :)
var string = "firstName:name1, lastName:last1";
var pass = string.replace(',',':');
var arr = pass.split(':');
var empty = {};
arr.forEach(function(el,i){
var b = i + 1, c = b/2, e = c.toString();
if(e.indexOf('.') != -1 ) {
empty[el] = arr[i+1];
}
});
console.log(empty)
Here is my approach to handle some edge cases like having whitespaces and other primitive types as values
const str = " c:234 , d:sdfg ,e: true, f:null, g: undefined, h:name ";
const strToObj = str
.trim()
.split(",")
.reduce((acc, item) => {
const [key, val = ""] = item.trim().split(":");
let newVal = val.trim();
if (newVal == "null") {
newVal = null;
} else if (newVal == "undefined") {
newVal = void 0;
} else if (!Number.isNaN(Number(newVal))) {
newVal = Number(newVal);
}else if (newVal == "true" || newVal == "false") {
newVal = Boolean(newVal);
}
return { ...acc, [key.trim()]: newVal };
}, {});
In your case
var KeyVal = string.split(", ");
var obj = {};
var i;
for (i in KeyVal) {
KeyVal[i] = KeyVal[i].split(":");
obj[eval(KeyVal[i][0])] = eval(KeyVal[i][1]);
}
var stringExample = "firstName:name1, lastName:last1 | firstName:name2, lastName:last2";
var initial_arr_objects = stringExample.split("|");
var objects =[];
initial_arr_objects.map((e) => {
var string = e;
var fields = string.split(','),fieldObject = {};
if( typeof fields === 'object') {
fields.forEach(function(field) {
var c = field.split(':');
fieldObject[c[0]] = c[1]; //use parseInt if integer wanted
});
}
console.log(fieldObject)
objects.push(fieldObject);
});
"objects" array will have all the objects
I know this is an old post but didn't see the correct answer for the question.
var jsonStrig = '{';
var items = string.split(',');
for (var i = 0; i < items.length; i++) {
var current = items[i].split(':');
jsonStrig += '"' + current[0] + '":"' + current[1] + '",';
}
jsonStrig = jsonStrig.substr(0, jsonStrig.length - 1);
jsonStrig += '}';
var obj = JSON.parse(jsonStrig);
console.log(obj.firstName, obj.lastName);
Now you can use obj.firstName and obj.lastName to get the values as you could do normally with an object.
You don't have to always convert to JSON
So here "person begin as a string!" Finally, "person is converted to object", no necessarily to JSON.
function strToObj(e){if(typeof e=="string"){ let obj=new Function("return" +e); try{return obj()}catch{console.log("Fix, String no allowed to object")}}else{console.log("it is not a string") } };
//Example, person is a string
let person='{firstName:"John", lastName:"Doe", id: 55, fullName:function(){return this.firstName+" "+this.lastName} }';
console.log(strToObj(person));
And it run functions internal to the object without major issues if it is called:
person=strToObj(person); console.log(person.fullName())
Simply, string = "firstName:name1, lastName:last1";
let string = "firstName:name1, lastName:last1";
let object= strToObj("{"+string+"}");
console.log(object)

Categories

Resources