Reputation: 113
Can someone help me turn this
entry = [
"start": "07:00 pm",
"end": "07:45 pm",
"rule": "MO,WE", <<<<
"summary": "test1"
];
into:
array = [
{
"start": "07:00 pm",
"end": "07:45 pm",
"rule": "MO,WE",
"summary": "test1",
"day": "WE" <<<<
},
{
"start": "07:00 pm",
"end": "07:45 pm",
"rule": "MO,WE",
"summary": "test1",
"day": "WE" <<<< (I get this but instead it should be "MO")
}
];
here is the code that I tried for getting the array... but it didn't work...
var temprule = entry.rule; //"MO,WE"
var rulest =[];
rulest = temprule.split(',');
for(var j = 0; j < rulest.length; j++) {
var obj1 = Object.assign(rulest[j]);
entry.day = obj1; //getting only WE each time when the array passes
jsondata.push(entry); // it has all elements like start,end,summary,rule and we need to add day to this...
}
I am not sure why it keeps adding same value in day though its looped through all different rules. Is that achievable throught code ?
Thanks!
Upvotes: 0
Views: 206
Reputation: 31682
// first of all this should be an object not an array
var entry = {
"start": "07:00 pm",
"end": "07:45 pm",
"rule": "MO,WE",
"summary": "test1"
};
// map the rules into a new aray
var result = entry.rule.split(',').map(function(r) {
var o = Object.assign({}, entry); // clone the object entry
o.day = r; // and set the clone's day to r
// uncomment the following line if you want to remove the property rule from the resultant objects
// delete o.rule; // remove the property rule from the clone
return o;
});
console.log(result);
Explanation of what is wrong with your code:
entry
is not a valid object (but that is not the main problem).Object.assign
's syntax is Object.assign(target, ...sources)
but you specify the target as the string rulest[j]
and no sources so the returned value is a string with the same content as the string rulest[j]
.day
of the object entry
and push it again and again for every iteration, and since objects are passed by reference not by value, all the items of the array will be a reference to the same object referred to by entry
. Changing one of them will alter all the other, so technically by the end you'll have all the items are the same object, and that object will have the property day
set to the last rule. What you have to do is to clone the object entry
using the right call to Object.assign
and then set its property day
to the current rule [, and probably remove the rule
property as it is not needed] and then push that cloned object instead of the entry
object.Example of the passed-by-reference thing I mentionned above:
var a = {
"foo": "bar"
};
var b = a; // not copied (a and b are the same object)
// PROOF:
b.stack = "overflow"; // here we change b (add the property stack to b)
console.log(a); // but yet a is changed too (even if we never did a.stack = ...)
Explanation of my code:
rule
property by ,
to get an array of rules.Array.prototype.map
. map
will call a function (its callback) on each item of the array and take the returned value of that function and push it into a new array, and when there is no items left from the source array (array of rules), it returns the generated array which will be of the same length.entry
using Object.assign
(the target is a new empty object {}
and the source is entry
of course). We then assign it's property day
to the current rule r
and return the object so map
will push it into the array that will be retuned after the work is done.EDIT:
Yes you can! You have to loop through the array and split the objects and push them into the resultant array. You can use Array.prototype.reduce
to simplify the job like this:
function convert(arr) { // take a array of objects arr and return a new array of objects
return arr.reduce(function(result, obj) { // for each object obj in the array arr
obj.rule.split(",").forEach(function(r) { // get its rule, split it by ',' and for each r in those parts
var o = Object.assign({}, obj); // clone the object obj
// delete o.rule; // remove rule from the resulatant object o (uncomment if you want to)
o.day = r; // set its day property to be the part r (the current part of the splitted rule)
result.push(o); // add the object to the result array
});
return result; // return the result so we can push to it more object (see the docs of reduce)
}, []); // initialize the result array with an empty array [] (see the docs of reduce)
}
var array = [
{"start": "07:00 pm", "end": "07:45 pm", "rule": "MO,WE", "summary": "test1"},
{"start": "07:00 pm", "end": "07:45 pm", "rule": "TU,TH", "summary": "test1"}
];
console.log(convert(array));
Docs of recude
on MDN.
Upvotes: 2
Reputation: 977
try this
var temprule = entry.rule; //"MO,WE"
var temprule_split = entry.rule.split(','); //split it
var rulest =[];
rulest = temprule.split(',');
for(var j = 0; j < rulest.length; j++) {
var obj1 = Object.assign(rulest[j]);
obj1.day=temprule_split[j];
entry.day = obj1;
jsondata.push(entry);
}
Upvotes: 0