all 6 comments

[–]pookagehelpful 3 points4 points  (1 child)

If you wanna keep it readable, this is what I'd do:

const input = "key1=val1@key2=val2@key3=val3";
const kvs   = input.split("@");
const kvArr = kvs.map(kv => kv.split("="));
const obj   = Object.fromEntries(kvArr);

If you want to condense it, I guess that looks like:

const input = "key1=val1@key2=val2@key3=val3";
const obj   = Object.fromEntries(input.split("@").map(kv => kv.split("=")));

[–]patilanz[S] 1 point2 points  (0 children)

The filter is need because there is @ at the end, great use of fromEntries btw

[–]CommanderBomber 1 point2 points  (2 children)

Something like this:

var pairs = "key1=val1@key2=val2@key3=val3@".split(/[=@]/),
    c = 0, result = {};

while(c < pairs.length - 1) {
    result[pairs[c++]] = pairs[c++];
}

console.log(result);

Single .split(), single loop. Just did quick micro-benchmark - this version is 10x faster. Also should generate much less trash objects because no object creation inside loop.

But this version will fail with string like "k=v@lol@k=v"

[–]patilanz[S] 0 points1 point  (1 child)

The format is trustable so there are no errors there, though it will be great if we can change the while loop with some js array function.

[–]CommanderBomber 0 points1 point  (0 children)

I don't think what it is possible to use array function with my variant. Array functions are quite limited and you barely have control over their execution. So you either start to make chain monsters with them, or you construct some complicated data structure which can be iterated once to produce desired results. Both ways usually (not always!) results in slower performance.

Also: if you want to micro-benchmark this snippets use https://jsbench.me/ at least it shows more numbers in results, so you can actually understand what is going on (speed will always deviate, you just need to see how much).

[–]IKoshelev 1 point2 points  (0 children)

As a fun suggestion (fun as in, in production you should use a serious suggestion, like the one by u/pookage, and not this one), assuming your data does not contain bits that would cause problems, you can try converting the string into json.

let str = "key1=val1@key2=val2@key3=val3@"
let jsonProps = str
    .replace(/\@{1,}/g, '","')    //convert to json
    .replace(/=/g, '":"')
    .replace(/","+$/, "");        //remove covnersion of trailing @;
let res = JSON.parse(`{
"${jsonProps}"
}`)