Reputation: 111
I have this string (which is called data)
||id: ticket/327364|Subject: TestSubject|Due: 2018||--||id: ticket/327366|Subject: TestTwo|Due: 2018|||
That I want to turn into an object that is accessible using key/values. Step 1 is splitting the string on "--" and removing all the "|" signs. Which I did like this
var dataArray = [];
data.split("--").forEach(function(x) {
var arr = x.split("|");
arr = arr.filter(function(e) {
return e;
});
dataArray.push(arr);
});
This gives me a multidimensional array
[Array(3), Array(3)]
0: ["id: ticket/327364", "Subject: Beställning av inkoppling", "Due: Ej inställd"]
1: ["id: ticket/327366", "Subject: Beställning av inkoppling", "Due: Ej inställd"]
And this is where I am stuck, because I want to split each of these arrays on ":". So Object.Due will give me the due-date and Object.Subject gives me the Subject etc. Also, it's not always going to be id, Subject, and Due. Sometimes it might be less or more entries.
I have tried this
var result = {};
dataArray.forEach(function(x) {
x.forEach(function(y) {
var newArr = y.split(":");
newArr[1] && (result[newArr[0]] = newArr[1]);
});
});
Which gives me exactly what I want, it gives me an object like this.
{id: " ticket/327366", Subject: " TestTwo", Due: " 2018"}
However, result only contains the data from the last array. It's like it overwrites the first one. Any suggestions on how to re-do this? Also, it feels like an awful lot of loops but I've only been dabbling with JS for a day or two so I haven't really figured out a different way of doing it.
Upvotes: 0
Views: 85
Reputation: 3958
Here's a different approach that avoids unwanted referencing:
const input = '||id: ticket/327364|Subject: TestSubject|Due: 2018||--||id: ticket/327366|Subject: TestTwo|Due: 2018|||';
const result = input
.split('--')
.map(subArray => {
const resultObject = {};
const filtered = subArray
.split('|')
.filter(item => item.length > 0);
for (let element of filtered) {
const [key, value] = element.split(':');
resultObject[key] = value.trim();
}
return resultObject;
});
console.log(result);
In your version, you are setting the value of the respective key to the new value, since the objects have repeated keys, they are being overwritten by the latest.
Upvotes: 1
Reputation: 350147
In the second code block you are building only one object: you want an array, yet result
is not an array. Move that object declaration inside the outer loop, and push that object to the final array at the end of each iteration. See the comments in your code where I made changes:
var data = '||id: ticket/327364|Subject: TestSubject|Due: 2018||--||id: ticket/327366|Subject: TestTwo|Due: 2018|||';
var dataArray = [];
data.split("--").forEach(function(x) {
var arr = x.split("|");
arr = arr.filter(function(e) {
return e;
});
dataArray.push(arr);
});
var resultArray = []; // <--- final array
dataArray.forEach(function(x) {
var result = {}; // <--- one object per iteration
x.forEach(function(y) {
var newArr = y.split(":");
newArr[1] && (result[newArr[0]] = newArr[1]);
});
resultArray.push(result); // <--- push it
});
console.log(resultArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here is an alternative way, which uses several ES6 features such as spread syntax, arrow functions, Object.assign
and computed property syntax:
const data = '||id: ticket/327364|Subject: TestSubject|Due: 2018||--||id: ticket/327366|Subject: TestTwo|Due: 2018|||';
const dataArray = data.split("--").map(x =>
Object.assign(...
x.split("|")
.filter(e => e)
.map(s => s.split(':'))
.map(([key, value]) => ({ [key]: value.trim() }))
)
);
console.log(dataArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 664405
You want one result per dataArray
entry, not one overall. So put the object creation it in the right place, and collect them in an array:
var results = dataArray.map(function(x) {
var result = {};
for (var y of x) {
var newArr = y.split(":");
if (newArr[1]) result[newArr[0]] = newArr[1];
}
return result;
});
Upvotes: 1
Reputation: 32
Well, that's because, as I understand, you are creating a single object each time in the result variable, so you are overwriting the result at each time in the loop. I think you sould insert the result object in an Array of results and iterate through it inserting in every cicle of the loop the result in the array with .push().
Don't know if that make sense for you.
Upvotes: 1