Home > Mobile >  How do I convert a string to a dictionary in javascript?
How do I convert a string to a dictionary in javascript?

Time:04-25

I have a string

var str = "1:6,5,2,2:3";

I want to convert this str into a js dictionary such that:

var dict = {1:"6,5,2",
            2:"3"};

so that I can fetch the values by their respective key index. How do I convert it?

I had tried this code to store the splitted values into an array:

var pages = "1:6,5,2,2:3";
var numbers = [];
if (pages.includes(',')) {
  page_nos = pages.split(',');
  for (var i = 0; i < page_nos.length; i  ) {
    if (page_nos[i].includes(':')) {
      var n = page_nos[i].split(':');
      numbers.push(n[1]);
    } else {
      numbers.push(page_nos[i]);
    }
  }
} else {
  page_nos = pages.split(':');
  numbers.push(page_nos[1])
};

console.log('numbers: ', numbers);

But it's incorrect, as without dictionary it's impossible to know what value belongs to which index

CodePudding user response:

If you cannot make your input string a proper JSON or another easily parsable format in the first place, this answers your question:

const str = "1:6,5,2,2:3";

const obj = str.split(/,(?=\d :)/).reduce((accu, part) => {
  const [k, v] = part.split(':', 2);
  accu[k] = v;
  return accu;
}, {});
console.log(obj);

Cut the string at all commas that are followed by digits and a colon. Each part has a key in front of a colon and a value after it, which should be stuffed in an object in this format.

CodePudding user response:

No mutations solution.

const str = "1:6,5,2,2:3";

const dict = str
  .split(/(\d :.*)(?=\d :)/g)
  .reduce((t, c) => {
    const [key, value] = c.replace(/,$/, "").split(/:/);
    return { ...t, [key]: value }
  });

  
console.log(dict);

CodePudding user response:

if you consider not using regular expression, you might try this as well. to take out a dict (Object) from that string, this will do.

var pages = "1:6,5,2,2:3";

function stringToObject(str) {
    
  var page_object = {};

  var last_object;

  str.split(",").forEach((item) => {
    if (item.includes(":")) {
      page_object[item.split(":")[0]] = item.split(":")[1];

      last_object = item.split(":")[0];
    } else {
      page_object[last_object]  = `,${item}`;
    }
  });
  return page_object;
}

console.log(stringToObject(pages))

CodePudding user response:

Presented below may be one possible solution to achieve the desired objective.

NOTE: In lieu of var the code uses either let or const as applicable.

Code Snippet

const pages = "1:6,5,2,2:3";
const resObj = {};
let page_nos, k;
if (pages.includes(',')) {
  page_nos = pages.split(',');
  for (let i = 0; i < page_nos.length; i  ) {
    if (page_nos[i].includes(':')) {
      let n = page_nos[i].split(':');
      k = n[0];
      resObj[k] = n[1].toString();
    } else {
      resObj[k]  = ", "   page_nos[i].toString();
    }
  }
} else {
  page_nos = pages.split(':');
  resObj[page_nos[0]] = [page_nos[1]]
  numbers.push(page_nos[1])
};

console.log('result object: ', resObj);

This code essentially fixes the code given in the question. It is self-explanatory and any specific information required may be added based on questions in comments.

CodePudding user response:

You could take nested splitring for entries and get an object from it.

const
    str = "1:6,5,2,2:3",
    result = Object.fromEntries(str
        .split(/,(?=[^,]*:)/)
        .map(s => s.split(':'))
    );

console.log(result);

  • Related