遍历每个嵌套对象并为每个嵌套对象创建一个div

时间:2018-03-26 16:36:06

标签: javascript node.js recursion data-structures ejs

使用以下对象,我需要使用EJS为该数组中的每个obj创建一个HTML div元素。

div应该是这样的:

<div>
    <div>Original comment</div>
    <div>The replies of that original comment</div>
    <div>The replies of the replies etc</div>
</div>

使用第一个对象的真实信息:

<div>
    <div>First updated comment</div>
    <div>This is a reply to comment ID 1(the comment above)</div>
    <div>reply to reply ID 5(the reply above)</div>
</div>

(当然如果“回复回复”有回复,那么它也需要在那个div中)

对象本身:

let obj = [
    {
        "id": 1, "comment": "First Updated Comment", "parentID": null, "replies": [{
            "id": 5, "comment": "This is a reply to comment ID 1", "parentID": 1, "replies":
                [{ "id": 9, "comment": "reply To reply ID 5", "parentID": 5, "replies": [] }]
        }]
    },
    { "id": 2, "comment": "Second Comment", "parentID": null, "replies": [] },
    { "id": 3, "comment": "Third Comment", "parentID": null, "replies": [] },
    { "id": 4, "comment": "4th Comment", "parentID": null, "replies": [{ "id": 6, "comment": "Reply to Comment ID 4 ", "parentID": 4, "replies": [] }] },
    { "id": 7, "comment": "Testing BLACK ", "parentID": null, "replies": [] },
    { "id": 8, "comment": "TriHard 7 comment id 7", "parentID": null, "replies": [] }
];

感谢您的时间

1 个答案:

答案 0 :(得分:0)

您可以使用Array.prototype.flatMap

执行此操作
const transform = ({ comment = "", replies = [] }) =>
  [ comment, ...replies.flatMap (transform) ]

console.log (obj.map (transform))
// [
//   [
//     "First Updated Comment",
//     "This is a reply to comment ID 1",
//     "reply To reply ID 5"
//   ],
//   [
//     "Second Comment"
//   ],
//   [
//     "Third Comment"
//   ],
//   [
//     "4th Comment",
//     "Reply to Comment ID 4 "
//   ],
//   [
//     "Testing BLACK "
//   ],
//   [
//     "TriHard 7 comment id 7"
//   ]
// ]

如果您还没有它,可能需要在您的环境中对其进行填充

Array.prototype.flatMap = function (f)
{
  return this.reduce ((acc, x) => acc.concat (f (x)), [])
}

程序演示

let obj = [
    {
        "id": 1, "comment": "First Updated Comment", "parentID": null, "replies": [{
            "id": 5, "comment": "This is a reply to comment ID 1", "parentID": 1, "replies":
                [{ "id": 9, "comment": "reply To reply ID 5", "parentID": 5, "replies": [] }]
        }]
    },
    { "id": 2, "comment": "Second Comment", "parentID": null, "replies": [] },
    { "id": 3, "comment": "Third Comment", "parentID": null, "replies": [] },
    { "id": 4, "comment": "4th Comment", "parentID": null, "replies": [{ "id": 6, "comment": "Reply to Comment ID 4 ", "parentID": 4, "replies": [] }] },
    { "id": 7, "comment": "Testing BLACK ", "parentID": null, "replies": [] },
    { "id": 8, "comment": "TriHard 7 comment id 7", "parentID": null, "replies": [] }
];

Array.prototype.flatMap = function (f)
{
  return this.reduce ((acc, x) => acc.concat (f (x)), [])
}

const transform = ({ comment = "", replies = [] }) =>
  [ comment, ...replies.flatMap (transform) ]
  
console.log (obj.map (transform))

// [
//   [
//     "First Updated Comment",
//     "This is a reply to comment ID 1",
//     "reply To reply ID 5"
//   ],
//   [
//     "Second Comment"
//   ],
//   [
//     "Third Comment"
//   ],
//   [
//     "4th Comment",
//     "Reply to Comment ID 4 "
//   ],
//   [
//     "Testing BLACK "
//   ],
//   [
//     "TriHard 7 comment id 7"
//   ]
// ]

如果您不习惯接触原生原型,只需将flatMap作为自己的功能

const flatMap = (f, xs = []) =>
  xs.reduce ((acc, x) => acc.concat (f (x)), [])

const transform = ({ comment = "", replies = [] }) =>
  [ comment, ...flatMap (transform, replies) ]

console.log (obj.map (transform))
// same output as above

上面,我们只是从每个节点收集comment文本字段,但我们也可以收集复合值

const transform = ({ id = null, parentID = null, comment = "", replies = [] }) =>
  [ { id, parentID, comment }, ...flatMap (transform, replies) ]

console.log (obj.map (transform))

// [
//   [ 
//     { id: 1, parentID: null, comment: 'First Updated Comment' },
//     { id: 5, parentID: 1, comment: 'This is a reply to comment ID 1' },
//     { id: 9, parentID: 5, comment: 'reply To reply ID 5' }
//   ],
//   [ 
//     { id: 2, parentID: null, comment: 'Second Comment' }
//   ],
//   [
//     { id: 3, parentID: null, comment: 'Third Comment' }
//   ],
//   [
//     { id: 4, parentID: null, comment: '4th Comment' },
//     { id: 6, parentID: 4, comment: 'Reply to Comment ID 4 ' }
//   ],
//   [
//     { id: 7, parentID: null, comment: 'Testing BLACK ' }
//   ],
//   [
//     { id: 8, parentID: null, comment: 'TriHard 7 comment id 7' }
//   ]
// ]

StackOverflow包含对React的支持,因此我们可以在下面演示完整的程序。其他模板语言(如ejs)的用户必须对其进行调整以满足他们的需求。

const Comment = ({ id, parentID, comment }) =>
  <div className="comment" data-id={id} data-parent={parentID}>
    {comment}
  </div>

const Discussion = (comments) =>
  <div className="discussion">{comments.map (Comment)}</div>

ReactDOM.render(<div>{ result.map (Discussion) }</div>, target)

const data =
  [{"id": 1, "comment": "First Updated Comment", "parentID": null, "replies": [{"id": 5, "comment": "This is a reply to comment ID 1", "parentID": 1, "replies":[{ "id": 9, "comment": "reply To reply ID 5", "parentID": 5, "replies": [] }]}]},{ "id": 2, "comment": "Second Comment", "parentID": null, "replies": [] },{ "id": 3, "comment": "Third Comment", "parentID": null, "replies": [] },{ "id": 4, "comment": "4th Comment", "parentID": null, "replies": [{ "id": 6, "comment": "Reply to Comment ID 4 ", "parentID": 4, "replies": [] }] },{ "id": 7, "comment": "Testing BLACK ", "parentID": null, "replies": [] },{ "id": 8, "comment": "TriHard 7 comment id 7", "parentID": null, "replies": [] }]

const Comment = ({ id, parentID, comment }) =>
  <div className="comment" data-id={ id } data-parent={ parentID }>
    {comment}
  </div>
  
const Discussion = (comments) =>
  <div className="discussion">{ comments.map (Comment) }</div>
  
const flatMap = (f, xs = []) =>
  xs.reduce ((acc, x) => acc.concat (f (x)), [])
  
const transform = ({ id = null, parentID = null, comment = "", replies = [] }) =>
  [ { id, parentID, comment }, ...flatMap (transform, replies) ]
 
const result =
  data.map (transform)

const target =
  document.getElementById ('main')
  
ReactDOM.render(<div>{ result.map (Discussion) }</div>, target)
.discussion {
  border: 1px solid blue;
  padding: 0.25rem;
  margin-bottom: 1rem;
}

.comment ~ .comment {
  padding-left: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="main"></div>