1

This is the value of a textarea:

STORY 01---abc
STORY 02---def
STORY 03---ghi

From the above I need an object:

{"STORY 01":"abc","STORY 02":"def","STORY 03":"ghi"}

My try - without success:

let obj = {};
let arr = $('#txa').val().split('\n');
for(el of arr){
  let a = el.split('---')[0];
  let b = el.split('---')[1];
  obj.a = b;
}

Result: a: "ghi"

Any help?

qadenza
  • 9,025
  • 18
  • 73
  • 126

4 Answers4

4

You need to use a string accessor

obj[a] = b

obj.a referes to the property 'a', obj[a] refers to the property with the key equal to the value of a

rh16
  • 1,056
  • 14
  • 24
4

You were close, but instead of dot (obj.a) notation, you have to use bracket (obj[a]) notation to set the new object keys. Otherwise you are always updating the key a of the object.

Also, note there is no need to duplicate the split() call, you can do it once and get both values from the resulting array.

let obj = {};
let arr = $('#myTArea').val().split('\n');

for (el of arr)
{
    let [a, b] = el.split('---');
    obj[a] = b;
}

console.log(obj);
console.log(obj["STORY 01"]);
console.log(obj["STORY 02"]);
console.log(obj["STORY 03"]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<textarea id="myTArea">STORY 01---abc
STORY 02---def
STORY 03---ghi</textarea>
Shidersz
  • 16,846
  • 2
  • 23
  • 48
  • Why I'm getting `STORY 01: "abc"` i.e. names without quotes? – qadenza Feb 18 '19 at 21:43
  • Because the object is a JavaScript object and that's how the specs are. You want JSON which you get when you `stringify` the object with `JSON.stringify(obj)` – Mouser Feb 18 '19 at 21:45
  • @Mouser, but in the `Shiders's` snippet there is no any `stringify` function? – qadenza Feb 18 '19 at 21:46
  • Well with my comment you can easily add that yourself. – Mouser Feb 18 '19 at 21:47
  • @Mouser, of course, thanks but the question is `Why...` – qadenza Feb 18 '19 at 21:49
  • https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation – Mouser Feb 18 '19 at 21:51
  • @Mouser, once again - code on my localhost and the code above are absolutelly the same - but my result is without quotes on the object names. Your link doesn't help to find the reason. – qadenza Feb 18 '19 at 21:55
  • @qadenza I can't figure out what you say (where do you get `keys` without quotes?), I have updated to show how to access particular elements of the created object. – Shidersz Feb 18 '19 at 21:56
  • @Shidersz, I'm getting this - `{STORY 01: "abc", STORY 02: "def", STORY 03: "ghi"} ` – qadenza Feb 18 '19 at 21:58
  • @qadenza That is rare, that is not a valid `key` identifier for what I have read here: https://mathiasbynens.be/notes/javascript-properties. Maybe your local environment just output the object that way. – Shidersz Feb 18 '19 at 22:00
  • Again getting JavaScript key values without quotes is perfectly legal and your code is working fine. If you want to have quotes around the key values convert it into a JSON string using `JSON.stringify(obj)`. In that way you can send it to another program. If you are planning to use `obj` in your JavaScript code it will work perfectly! – Mouser Feb 18 '19 at 22:12
  • @Mouser that's all truth, but that's not my question. – qadenza Feb 18 '19 at 22:13
2

Explanation

Using destructuring, String#match and Array#reduce

.match(/(?!\n).+/g) To get an array of each line.

For each line, split it with --- and update the accumolator (a) and return it.

.reduce((a,c)=>{
   const [key, value] = c.split("---");
   a[key]=value;
   return a;
 }, {});

Solution

const data = `
STORY 01---abc
STORY 02---def
STORY 03---ghi
`;

const res = data.trim()
 .match(/(?!\n).+/g)
 .reduce((a,c)=>{
   const [key, value] = c.split("---");
   a[key]=value;
   return a;
 }, {});

console.log(res);

Recommendation

I would re-organize the final output differently since your key has a space. Also taking input directly from the textarea and using it as a key is prone to user input errors.

const data = `
STORY 01---abc
STORY 02---def
STORY 03---ghi
`;

const res = data.trim()
 .match(/(?!\n).+/g)
 .map(c=>{
   const [key, value] = c.split("---");
   return {key, value};
 });

console.log(res);
kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131
1

The key is in adding properties to the obj using the bracket notation

I used a different approach using String.prototype.substring and Array.prototype.forEach

//vanilla solution - no jQuery

const obj = {}; //use constant since the variable itself won't change
const arr = document.querySelector("#myTArea").value.split('\n'); //same here
//since arr is the array containing the splitted values
//we can use array's forEach
arr.forEach(function(element){
  const delimiter = element.indexOf("-");
  const keyValue = element.substring(0, delimiter); 
  const value = element.substring(delimiter+3); //delimiter is 3 long, so index+3

  obj[keyValue] = value;
});
console.log(obj);
<textarea id="myTArea">STORY 01---abc
STORY 02---def
STORY 03---ghi</textarea>
Mouser
  • 13,132
  • 3
  • 28
  • 54