我想将showtimesData
转换为showtimesByLocationByDate
任何想法如何不使用任何第三方库,只使用纯JavaScript?否则,我可以使用哪个第三方库?
var showtimesData = [
{"location":"location1", "date":"31-12-2016", "time":"1:00"},
{"location":"location1", "date":"31-12-2016", "time":"2:00"},
{"location":"location1", "date":"01-01-2017", "time":"3:00"},
{"location":"location1", "date":"01-01-2017", "time":"4:00"},
{"location":"location2", "date":"31-12-2016", "time":"1:00"},
{"location":"location2", "date":"31-12-2016", "time":"2:00"},
{"location":"location2", "date":"01-01-2017", "time":"3:00"},
{"location":"location2", "date":"01-01-2017", "time":"4:00"},
];
var showtimesByLocationByDate = [
{
"location":"location1",
"dates":[
{
"date":"31-12-2016",
"times":["1:00","2:00"]
},
{
"date":"01-01-2017",
"times":["3:00","4:00"]
}
]
},
{
"location":"location2",
"dates":[
{
"date":"31-12-2016",
"times":["1:00","2:00"]
},
{
"date":"01-01-2017",
"times":["3:00","4:00"]
}
]
},
];
答案 0 :(得分:4)
此提案仅包含Array.prototype.reduce()
,其中包含一个用于引用数组项的临时对象。
var showtimesData = [{ "location": "location1", "date": "31-12-2016", "time": "1:00" }, { "location": "location1", "date": "31-12-2016", "time": "2:00" }, { "location": "location1", "date": "01-01-2017", "time": "3:00" }, { "location": "location1", "date": "01-01-2017", "time": "4:00" }, { "location": "location2", "date": "31-12-2016", "time": "1:00" }, { "location": "location2", "date": "31-12-2016", "time": "2:00" }, { "location": "location2", "date": "01-01-2017", "time": "3:00" }, { "location": "location2", "date": "01-01-2017", "time": "4:00" }, ],
showtimesByLocationByDate = showtimesData.reduce(function (r, a) {
var o;
if (!(a.location in r.obj)) {
o = { location: a.location, dates: [] };
r.obj[a.location] = { dates: o.dates };
r.array.push(o);
}
if (!(a.date in r.obj[a.location])) {
o = { date: a.date, times: [] };
r.obj[a.location].dates.push(o);
r.obj[a.location][a.date] = o.times;
}
r.obj[a.location][a.date].push(a.time);
return r;
}, { array: [], obj: {} }).array;
document.write('<pre>' + JSON.stringify(showtimesByLocationByDate, 0, 4) + '</pre>');
&#13;
奖励:具有给定数据结构的通用版本
var showtimesData = [{ "location": "location1", "date": "31-12-2016", "time": "1:00" }, { "location": "location1", "date": "31-12-2016", "time": "2:00" }, { "location": "location1", "date": "01-01-2017", "time": "3:00" }, { "location": "location1", "date": "01-01-2017", "time": "4:00" }, { "location": "location2", "date": "31-12-2016", "time": "1:00" }, { "location": "location2", "date": "31-12-2016", "time": "2:00" }, { "location": "location2", "date": "01-01-2017", "time": "3:00" }, { "location": "location2", "date": "01-01-2017", "time": "4:00" }, ],
structure = [
{ key: 'location', data: 'dates' },
{ key: 'date', data: 'times' },
{ key: 'time' }
],
showtimesByLocationByDate = showtimesData.reduce(function (r, a) {
var properties = structure.slice(),
lastKey = properties.pop().key;
properties.reduce(function (rr, b) {
var o = {},
p = {},
key = b.key,
value = a[key],
array = b.data;
if (!(value in rr.obj)) {
o[key] = value;
o[array] = [];
p[array] = o[array];
rr.obj[value] = p;
rr.array.push(o);
}
return { array: rr.obj[value][array], obj: rr.obj[value] };
}, r).array.push(a[lastKey]);
return r;
}, { array: [], obj: {} }).array;
document.write('<pre>' + JSON.stringify(showtimesByLocationByDate, 0, 4) + '</pre>');
&#13;
答案 1 :(得分:4)
我建议进行这种转变:
var showtimesData = [
{"location":"location1", "date":"31-12-2016", "time":"1:00"},
{"location":"location1", "date":"31-12-2016", "time":"2:00"},
{"location":"location1", "date":"01-01-2017", "time":"3:00"},
{"location":"location1", "date":"01-01-2017", "time":"4:00"},
{"location":"location2", "date":"31-12-2016", "time":"1:00"},
{"location":"location2", "date":"31-12-2016", "time":"2:00"},
{"location":"location2", "date":"01-01-2017", "time":"3:00"},
{"location":"location2", "date":"01-01-2017", "time":"4:00"},
];
var transformed = showtimesData.reduce(function(obj, show){
//var { location, date, time } = show; //if destructuring is available
var location = show.location,
date = show.date,
time = show.time,
objLocation = obj[location] = obj[location] || { dates : { } },
dates = objLocation.dates,
date = dates[date] = dates[date] || [ ];
date.push(time);
return obj;
}, {});
results.innerHTML = JSON.stringify(transformed, null, '\t');
&#13;
<pre id="results"></pre>
&#13;
但是如果你真的想把它改造成那样的话,我建议把它转换成你建议的结构。
var showtimesData = [
{"location":"location1", "date":"31-12-2016", "time":"1:00"},
{"location":"location1", "date":"31-12-2016", "time":"2:00"},
{"location":"location1", "date":"01-01-2017", "time":"3:00"},
{"location":"location1", "date":"01-01-2017", "time":"4:00"},
{"location":"location2", "date":"31-12-2016", "time":"1:00"},
{"location":"location2", "date":"31-12-2016", "time":"2:00"},
{"location":"location2", "date":"01-01-2017", "time":"3:00"},
{"location":"location2", "date":"01-01-2017", "time":"4:00"},
];
var transformed = showtimesData.reduce(function(obj, show){
//var { location, date, time } = show; //if destructuring is available
var location = show.location,
date = show.date,
time = show.time,
objLocation = obj[location] = obj[location] || { dates : { } },
dates = objLocation.dates,
date = dates[date] = dates[date] || [ ];
date.push(time);
return obj;
}, {});
var secondTransformed = Object.keys(transformed).map(function(key){
var dates = transformed[key].dates,
transformedDates = Object.keys(dates).map(function(key){
return { date : key, times : dates[key] }
});
return { location : key, dates : transformedDates }
});
results.innerHTML = JSON.stringify(secondTransformed, null, '\t');
&#13;
<pre id="results"></pre>
&#13;
虽然有更好的方法可以做到这一点(性能明智)。