1
Array.prototype.indicesOf = function (el) {
    let indices = [];
    for (var i = this.length - 1; i >= 0; i--) {
        if (this[i] === el)
          indices.unshift(i);
    }
    return indices;
}

class CommentNester {

  constructor(comments) {
    this.comments = comments;
    this.nestedComments = this.nest();
  }

  getComments() {
    return this.comments;
  }

  getNestedComments() {
    return this.nestedComments;
  }

  nest() {

    const comments = this.comments.slice();

    (function appendChildren(parent_id = null) {

      const childIndices = comments.map(comment => comment.parent_id).indicesOf(parent_id);

      childIndices.forEach(index => {
        const child = comments[index];

        if (parent_id) {
          const parentIndex = comments.findIndex(comment => comment.id === parent_id);
          if (!comments[parentIndex].children) {
             comments[parentIndex].children = [];
          }
          comments[parentIndex].children.push(child);
        }

        appendChildren(child.id);
      });

    })();

    return comments.filter(comment => comment.parent_id === null);
  }

}

const comments = [{
  id: 1,
  text: "Top level",
  parent_id: null
}, {
  id: 2,
  text: "Top level",
  parent_id: null
}, {
  id: 3,
  text: "Reply level 1",
  parent_id: 1
}, {
  id: 4,
  text: "Reply level 1",
  parent_id: 2
}, {
  id: 5,
  text: "Reply level 2",
  parent_id: 3
}];

getComments() shows the original comments array is mutated (it has children), but I want it to stay original. I'm using .slice() to create a copy, but for some reason it still gets mutated. Any ideas why?

Codepen here: http://codepen.io/anon/pen/QpMWNJ?editors=1010

frosty
  • 2,779
  • 6
  • 34
  • 63

2 Answers2

0

use object mapping,

const comments = this.comments.slice()
const cloneComments = comments.map(f => {
        let o = {}
        for(var i in f) o[i] = f[i]
        return o
    })
syarul
  • 2,161
  • 2
  • 20
  • 22
0

Your answer should be here - What is the most efficient way to deep clone an object in JavaScript?

If you want to avoid jQuery go for JSON.parse(JSON.stringify(obj)) solution const comments = JSON.parse(JSON.stringify(this.comments));

Note: This will break if there is a cyclic dependency

If you can use jQuery go for the cleaner approach using extend

// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);
Community
  • 1
  • 1
Gulfaraz Rahman
  • 417
  • 4
  • 13