We have:

[ { "EventStartDate": "17/10/2008", "EventType": "Restricted", "Event": "My Forum", "SessionStartTime": "18:00", "City": "Ryazan", "TypeSession": "1on1", "RowCount": 0 }, { "EventStartDate": "17/10/2008", "EventType": "Restricted", "Event": "My Forum", "SessionStartTime": "15:10", "City": "London", "TypeSession": "3on1", "RowCount": 1 }, { "EventStartDate": "24/11/2008", "EventType": "Conference", "Event": "AAA Test Event", "SessionStartTime": "15:10", "City": "Paris", "TypeSession": "Meeting", "RowCount": 2 }, { "EventStartDate": "24/11/2008", "EventType": "Conference", "Event": "AAA Test Event", "SessionStartTime": "16:10", "City": "Moscow", "TypeSession": "Breakfast", "RowCount": 3 } ] 

It is necessary to group sessions by date, by event type, by event name.

The final JSON seems correctly compiled:

 "17/10/2008": { "Restricted": { "My Forum": { "18:00": { "City": "Ryazan", "TypeSession": "1on1", "RowCount": 0 }, "15:10": { "City": "London", "TypeSession": "3on1", "RowCount": 1 } } } }, "24/11/2008": { "Conference": { "AAA Test Event": { "15:10": { "City": "Paris", "TypeSession": "Meeting", "RowCount": 2 }, "16:10": { "City": "Moscow", "TypeSession": "Breakfast", "RowCount": 3 } } } } } 

My script for looping through an array is incorrect.

 <script> var arr2 = []; for (var i = 0; i < arr1.length; i++) { if (arr2[arr1[i].EventStartDate] && arr2[arr1[i].EventStartDate].EventStartDate) { for (n in arr1[i]) { if (n != 'EventStartDate') { arr2[arr1[i].EventStartDate][n] = (arr2[arr1[i].EventStartDate][n]) ? arr2[arr1[i].EventStartDate][n] + ";" + arr1[i][n] : arr1[i][n]; } } } else { arr2[arr1[i].EventStartDate] = arr1[i]; } } console.log('result', arr2); </script> 

but he does not what I expected, it seems to me that I am not going the right way, send me)

  • Add an example of a real source json and an example of what should happen at the output - Grundy
  • @Grundy added. - re_void
  • Can't see an example of initial json? Yes, and the final json is also not visible. For what data is the final html given? - Grundy
  • @Grundy is now exactly as requested) - re_void
  • Great question. There is data, there is a desired result, there is a code. ) - Nick Volynkin

2 answers 2

It is convenient to use the reduce function for different groupings.

 var data = [{ "EventStartDate": "17/10/2008", "EventType": "Restricted", "Event": "My Forum", "SessionStartTime": "18:00", "City": "Ryazan", "TypeSession": "1on1", "RowCount": 0 }, { "EventStartDate": "17/10/2008", "EventType": "Restricted", "Event": "My Forum", "SessionStartTime": "15:10", "City": "London", "TypeSession": "3on1", "RowCount": 1 }, { "EventStartDate": "24/11/2008", "EventType": "Conference", "Event": "AAA Test Event", "SessionStartTime": "15:10", "City": "Paris", "TypeSession": "Meeting", "RowCount": 2 }, { "EventStartDate": "24/11/2008", "EventType": "Conference", "Event": "AAA Test Event", "SessionStartTime": "16:10", "City": "Moscow", "TypeSession": "Breakfast", "RowCount": 3 }]; var result = data.reduce(function(acc, cur) { var eventDate = acc[cur.EventStartDate]; //группируем по дате if (!eventDate) { eventDate = acc[cur.EventStartDate] = {}; } var eventType = eventDate[cur.EventType]; //группируем по типу if (!eventType) { eventType = eventDate[cur.EventType] = {}; } var eventName = eventType[cur.Event]; //группируем по названию if (!eventName) { eventName = eventType[cur.Event] = {}; } // если нужно хранить весь объект а не какие-то поля. то можно просто присвоить cur // eventName[cur.SessionStartTime] = cur; eventName[cur.SessionStartTime] = { "City": cur.City, "TypeSession": cur.TypeSession, "RowCount": cur.RowCount }; return acc; }, {}); document.write('<pre>' + JSON.stringify(result, null, 2) + '</pre>'); 

Can. also, a little generalize, as in the adjacent answer. But in my opinion readability deteriorated.

 var data = [{ "EventStartDate": "17/10/2008", "EventType": "Restricted", "Event": "My Forum", "SessionStartTime": "18:00", "City": "Ryazan", "TypeSession": "1on1", "RowCount": 0 }, { "EventStartDate": "17/10/2008", "EventType": "Restricted", "Event": "My Forum", "SessionStartTime": "15:10", "City": "London", "TypeSession": "3on1", "RowCount": 1 }, { "EventStartDate": "24/11/2008", "EventType": "Conference", "Event": "AAA Test Event", "SessionStartTime": "15:10", "City": "Paris", "TypeSession": "Meeting", "RowCount": 2 }, { "EventStartDate": "24/11/2008", "EventType": "Conference", "Event": "AAA Test Event", "SessionStartTime": "16:10", "City": "Moscow", "TypeSession": "Breakfast", "RowCount": 3 }]; var result = data.reduce(function(acc, cur) { var group = acc.groupKeys.reduce(function(groupObject, currentGroupKey) { var g = groupObject[cur[currentGroupKey]]; if (!g) g = groupObject[cur[currentGroupKey]] = {}; return g; }, acc.result); group[cur[acc.lastGroupKey]] = acc.selectKeys.reduce(function(selectObject, selectKey) { selectObject[selectKey] = cur[selectKey]; return selectObject; }, {}); return acc; }, { lastGroupKey: "SessionStartTime", groupKeys: ["EventStartDate", "EventType", "Event"], selectKeys: ["City", "TypeSession", "RowCount"], result: {} }).result; document.write('<pre>' + JSON.stringify(result, null, 2) + '</pre>'); 

  • Thank! I also like the first option more and are completely understandable, nothing complicated. For the first time I try to work with JSON. And you can’t tell me how to put the markup on html now, because now there are no explicit keys as the name of the fields, and the data can be any at all. - re_void
  • @re_void, the for...in loop traverses all the object keys. In addition, you can try to skip the construction of the final js and instead collect the jQuery object immediately, which you then insert where necessary. But here we have to look at the final markup - Grundy
  • for for...in keys are not known to me, but the markup is exactly like every block by Date, and then the elements are in the same order as in JSON. - re_void
  • @re_void, for..in - just the keys and returns, here and do each block by Date, and then by elements of the order as in JSON :) - Grundy
  • Well, thank you very much.) - re_void

 let source = JSON.parse(`[{ "EventStartDate": "17/10/2008", "EventType": "Restricted", "Event": "My Forum", "SessionStartTime": "18:00", "City": "Ryazan", "TypeSession": "1on1", "RowCount": 0 }, { "EventStartDate": "17/10/2008", "EventType": "Restricted", "Event": "My Forum", "SessionStartTime": "15:10", "City": "London", "TypeSession": "3on1", "RowCount": 1 }, { "EventStartDate": "24/11/2008", "EventType": "Conference", "Event": "AAA Test Event", "SessionStartTime": "15:10", "City": "Paris", "TypeSession": "Meeting", "RowCount": 2 }, { "EventStartDate": "24/11/2008", "EventType": "Conference", "Event": "AAA Test Event", "SessionStartTime": "16:10", "City": "Moscow", "TypeSession": "Breakfast", "RowCount": 3 }]`), result = {}, data = [ ['EventStartDate', 'EventType', 'Event', 'SessionStartTime'], // Цепочка вложенностей; порядок важен, ибо зависит результат ['City', 'TypeSession', 'RowCount'] // Ключи по которым нужно помещать в результатЪ ]; source.forEach(e => { // Перебираем все элементы событий let ref = result, // Ставим локальную ссылку на результат obj = {}; for(let id in data[1]) obj[data[1][id]] = e[data[1][id]]; // Создаём объект с значениями из data[1], который положим в результат data[0].slice(0, -1).forEach(id => { // Создаём/получаем по очереди всю цепочку (кроме последнего элемента) из data[0] if(!(e[id] in ref)) ref[e[id]] = {}; ref = ref[e[id]]; }); ref[e[data[0][data[0].length - 1]]] = obj; // Вставляем событие по последнему ключу из data[0] }); console.dir(result); 

Note: Under the conditions, nothing is said about multiple events of the same type, date, name, and time. That is, if everything in the chain matches, then the last event will overwrite the rest. I wanted to put them in an array, if they match, but decided without amateur performance.
Yes, and they are unlikely to coincide at all, right?

  • Yes, it can not completely coincide, it can only coincide: the date, type, name of the event, the rest is already in love in separate branches. Thanks a great option! Only the date format \ time swears, but I corrected myself. For the first time, I deal with JSON, as if now this html template is adequately stretched. - re_void