Creation of object with key/value pairs in a string?

时间:2018-02-26 17:47:29

标签: javascript arrays regex string object

I have the following string:

person:juan&age:24&knowledge:html

The problem is that sometimes the string is:

knowledge:html&person:juan&age:24

And it can change the position of the keys and the values.

In this case I would write something like this:

const keys = ["person", "age", "knowledge"];
const keyAndValues = "person:juan&age:24&knowledge:html";

const result = [];

keys.forEach(key => {
  const indexKeyValues = keyAndValues.indexOf(key);
  if (indexKeyValues !== -1) {
    const lastCharIndex = keyAndValues.substring(indexKeyValues).indexOf("&");
    return keyAndValues.substring(indexKeyValues + key.length, lastCharIndex === -1 ? keyAndValues.substring(indexKeyValues).length - 1 || lastCharIndex);
  }
});

But I don't like it and it would be great if I could do something like:

const resultsExpected = /regexGroupedRegardlessOfPosition/g.match("person:juan&age:24&knowledge:html");

console.log(resultsExpected); // { person: "juan", age: 24, knowledge: "html" }

6 个答案:

答案 0 :(得分:3)

You could split the string and then the parts and take the key/values for an object.

function getValues(string) {
    var object = {};
    
    string && string.split('&').forEach(p => {
        var [key, ...value] = p.split(':');
        object[key] = value.join(':');
    });
    return object;
}

console.log(getValues("knowledge:html&person:juan&age:24"));
console.log(getValues("foo:bar:baz&cool:space:aliens:survive"));
console.log(getValues(""));

答案 1 :(得分:3)

Here is a single expression to get the object:

const keyAndValues = "person:juan&age:24&knowledge:html";

const obj = Object.assign(...keyAndValues.split('&').map(s => s.split(':'))
                                         .map(([k, v]) => ({ [k]: v }))
);

console.log(obj);

This uses ES6 destructuring assignment, spread syntax and computed property names.

答案 2 :(得分:2)

(knowledge|person|age):([^&]+)

You probably don't want to, but to accept any key:

(\w+):([^&]+)

https://regex101.com/r/HwW5I1/1/

答案 3 :(得分:1)

As Phiter said, I don't think regex really helps you here. You probably know the old joke: "I have a problem. I know! I'll use regex! Oh, now I have two problems."

I'd split the string on &, and then for each substring, on :, and fill in the values from that:

function strToObject(str) {
  var rv = {};
  str.split("&").forEach(function(substr) {
    var index = substr.indexOf(":");
    if (index === -1) {
      rv[substr] = undefined;
    } else {
      rv[substr.substring(0, index)] = substr.substring(index+1);
    }
  });
  return rv;
}

Live Example:

function strToObject(str) {
  var rv = {};
  str.split("&").forEach(function(substr) {
    var index = substr.indexOf(":");
    if (index === -1) {
      rv[substr] = undefined;
    } else {
      rv[substr.substring(0, index)] = substr.substring(index+1);
    }
  });
  return rv;
}

console.log(strToObject("person:juan&age:24&knowledge:html"));
console.log(strToObject("knowledge:html&person:juan&age:24"));
.as-console-wrapper {
  max-height: 100% !important;
}

This could be made terser, by:

  • Using ES2015+ syntax.
  • By creating unnecessary temporary objects (JavaScript engines are quick at creating and destroying objects, though, so the brevity can be worth the cost).
  • Assuming values never contain : characters. I've used indexOf rather than the simpler split to separate name and value to allow for the possibility that the value will contain a : (e.g., foo:blah:blah&bar:blah where foo is "blah:blah") — many if not most other solutions here throw away part of the value in that case

答案 4 :(得分:1)

I think a simple function that would convert this type of string to an object can be a better solution. Look at this:

var keyAndValues = "person:juan&age:24&knowledge:html";

function weirdStringToObject(str){
    var obj = {};
    str.split('&').forEach(function(substr){
        var kv = substr.split(':');
        var key = kv[0];
        var value = kv[1] || null;
        obj[key] = value;
    });
    return obj;
}

console.log(weirdStringToObject(keyAndValues));

It requires a little bit of extra validation, but it's easy to follow from here.

答案 5 :(得分:1)

You can make use of:

Working Example:

const str = "person:juan&age:24&knowledge:html";

let result = str.split("&").reduce((r, s) => {
  let i = s.indexOf(':');
  r[s.slice(0, i)] = s.slice(i + 1);
  return r;
}, {});

console.log(result);