Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
160 views
in Technique[技术] by (71.8m points)

javascript - Combine array into multiple levels

i have 1 array

datas = [
 {
   "num": 1,
   "url": "/a2-1/learning/01-001-01-01/",
   "old_content_id": "01-001-01-01-01",
   "content_id": "01-001-01-01",
   "topic": 1,
   "lesson": 1,
   "cando": 1,
   "study_type": "タイトル提示",
   "progress_type": "lesson_start",
   "template_type": "iro-tpl_01",
   "step": 1,
   "unit": 1,
   "unit_type": "トピックを知る",
   "order": 1,
   "directive_type": "",
   "ref_vocabulary": "",
   "ref_tips": "",
   "ref_help": "",
   "ref_example": "",
   "prev_content_id": null,
   "next_content_id": "01-001-02-01",
   "unit_id": "01-001-01",
   "prev_content_url": null,
   "next_content_url": "/a2-1/learning/01-001-02-01/",
   "directive_icon_id": null
 },
 {
   "num": 2,
   "url": "/a2-1/learning/01-001-02-01/",
   "old_content_id": "01-001-01-01-02",
   "content_id": "01-001-02-01",
   "topic": 1,
   "lesson": 1,
   "cando": 1,
   "study_type": "動画提示",
   "progress_type": "lesson_start",
   "template_type": "iro-tpl_02",
   "step": 1,
   "unit": 2,
   "unit_type": "ストーリーを知る",
   "order": 1,
   "directive_type": "動画",
   "ref_vocabulary": "",
   "ref_tips": "",
   "ref_help": "",
   "ref_example": "",
   "prev_content_id": "01-001-01-01",
   "next_content_id": "01-001-02-02",
   "unit_id": "01-001-02",
   "prev_content_url": "/a2-1/learning/01-001-01-01/",
   "next_content_url": "/a2-1/learning/01-001-02-02/",
   "directive_icon_id": 12
 },
 {
   "num": 3,
   "url": "/a2-1/learning/01-001-02-02/",
   "old_content_id": "01-001-01-01-03",
   "content_id": "01-001-02-02",
   "topic": 1,
   "lesson": 1,
   "cando": 1,
   "study_type": "問いかけ",
   "progress_type": "lesson_start",
   "template_type": "iro-tpl_03",
   "step": 1,
   "unit": 2,
   "unit_type": "ストーリーを知る",
   "order": 2,
   "directive_type": "",
   "ref_vocabulary": "",
   "ref_tips": "",
   "ref_help": "",
   "ref_example": "",
   "prev_content_id": "01-001-02-01",
   "next_content_id": "01-001-03-01",
   "unit_id": "01-001-02",
   "prev_content_url": "/a2-1/learning/01-001-02-01/",
   "next_content_url": "/a2-1/learning/01-001-03-01/",
   "directive_icon_id": null
 },
 {
   "num": 4,
   "url": "/a2-1/learning/01-001-03-01/",
   "old_content_id": "01-001-01-02-01",
   "content_id": "01-001-03-01",
   "topic": 1,
   "lesson": 1,
   "cando": 1,
   "study_type": "目標提示",
   "progress_type": "",
   "template_type": "iro-tpl_04",
   "step": 1,
   "unit": 3,
   "unit_type": "目標を知る",
   "order": 1,
   "directive_type": "目標Can-do",
   "ref_vocabulary": "",
   "ref_tips": "",
   "ref_help": "",
   "ref_example": "",
   "prev_content_id": "01-001-02-02",
   "next_content_id": "01-001-04-01",
   "unit_id": "01-001-03",
   "prev_content_url": "/a2-1/learning/01-001-02-02/",
   "next_content_url": "/a2-1/learning/01-001-04-01/",
   "directive_icon_id": 9
 }
]

How can I pool it on these levels?

Topic > Lesson > cando > step > content? 

I use group by but can only group 1 level, later levels can't since it has changed to Ob

var groupBy = function (xs, key) {
  return xs.reduce(function (rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};
var groubedByTopic = groupBy(datas, "topic");
console.log(groubedByTopic );

result: https://gyazo.com/8bdc4a76fc8a316902f2cab96ea63679.

But then cannot continue on smaller levels such as lesson, canon ...

Do everyone have a way to combine them according to the above 4 levels?

This is the result I want, the remaining values will belong to the content https://gyazo.com/4a364d5f75e0bf60f3eea5e0ae6ff001

Hope everyone help, thank you.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

this way :

const treeRefs = 
  [ { key: 'topic_id',  ref:'topic',  grp: 'lesson'  } 
  , { key: 'lesson_id', ref:'lesson', grp: 'cando'   } 
  , { key: 'cando_id',  ref:'cando',  grp: 'step'    } 
  , { key: 'step_id',   ref:'step',   grp: 'content' } 
  ]

const result = { topic:[] } 

datas.forEach(row =>
  {
  let {topic,lesson,cando,step,...more} = row
    , wArr = result.topic
    ;
  treeRefs.forEach(({key,ref,grp},i)=>
    {
    let obj = wArr.find(x=>x[key]===row[ref])
    if (!obj)
      {
      obj = {[key]: row[ref], [grp]: [] }
      wArr.push(obj)
      }
    wArr = obj[grp]
    })
  wArr.push({...more})
  });

console.log(JSON.stringify(result,0,2))

it is the same method as here:
Javascript/nodejs dynamically build JS object with nested arrays
, but made in a generic way


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...