для ... утверждения первого обхода дерева JavaScript - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь обернуть голову вокруг объявления класса ES6, экземпляров класса, утверждения for ... и рекурсивного обхода дерева в глубину.

Вот мое дерево:

The house of Windsor

А вот и конструкция дерева:

// let index = Symbol('index');

class Royal {
  constructor(name, yearBorn) {
    this.name = name;
    this.yearBorn = yearBorn;
    this.royalParent = null;
    // this.royalChildren = [];
    this.royalChildren = new Array();
    // this[index] = 0;
  }

  // [Symbol.iterator]() {
  //   let index = 0;
  //     return {
  //       next: () => ({
  //         value: this.offspring[index++],
  //         done: index > this.offspring.length
  //     })
  //   };
  // }

  // Adds royal child as a child of this royal parent
  addRoyalChild(royalChild) {
    // this[this[index]] = royalChild;
    // this[index]++;

    royalChild.royalParent = this;
    this.royalChildren.push(royalChild);
    // console.log('this[index]: ', this[index]);
  }

  // Returns the total number of direct offspring of this royal parent
  get numberOfRoyalChildren() {
    return `Should be first royal child: ${this.royalChildren}`;
    // return this.royalChildren.length;
  }

  // Returns the number of generations away from the original royal (George V) that this royal is
  get numberOfStepsFromOriginal() {
    let numberOfSteps = 0;
    let currentRoyalChild = this;

    while (currentRoyalChild.royalParent) {
      currentRoyalChild = currentRoyalChild.royalParent;
      numberOfSteps++;
    }
    return numberOfSteps;
  }

  // Returns true if this royal is more senior than the other royal. i.e. Who is closer to the original royal?
  isMoreSeniorThan(royalChild) {
    if ((this.numberOfStepsFromOriginal - royalChild.numberOfStepsFromOriginal) < 0) {
      return true;
    }
    return false;
  }

  allRoyals() {
    let royals = [];
    if (Array.isArray(this.royalChildren)) {
      royals.push(this);
      for (const royalChild of this.royalChildren) {
        const royalChildrenArray = royalChild.allRoyals();
        royals = royals.concat(royalChildrenArray);
      }
    } else {
      console.log('Oy!');
    }
    return royals;
  }

  /** Tree traversal methods **/

  // Returns the royal object with that name, or null if no royal exists with that name
  royalWithName(name1, name2) {
    let royals = new Array();
    if (Array.isArray(this.royalChildren)) {
      if ((this.name === name1) || (this.name === name2)) {
        royals.push(this);
      }
      for (let royal of this.royalChildren) {
        let royalsWithMatchingName = new Array();
        royalsWithMatchingName = royal.royalWithName(name1, name2);
        royals = royals.concat(royalsWithMatchingName);
      }
    } else {
      return null;
    }
    return royals;
  }

  // Returns the number of descendents of a royal
  get totalDescendents() {
    return this.allRoyals().slice(1).length;
  }

}

const georgeV = new Royal('George V', 1865);
const edwardVIII = new Royal('Edward VIII', 1894);
const georgeVI = new Royal('George VI', 1895);
const elizabethII = new Royal('Elizabeth II', 1926);
const margaret = new Royal('Princess Margaret', 1930);
const charles = new Royal('Prince Charles', 1948);
const anne = new Royal('Princess Anne', 1950);
const andrew = new Royal('Prince Andrew', 1960);
const edward = new Royal('Prince Edward', 1964);
const william = new Royal('Prince William', 1982);
const harry = new Royal('Prince Harry', 1984);
const beatrice = new Royal('Princess Beatrice', 1988);
const eugenie = new Royal('Princess Eugenie', 1990);
const louise = new Royal('Lady Louise', 2003);
const severn = new Royal('Viscount Severn', 2007);

georgeV.addRoyalChild(edwardVIII);
georgeV.addRoyalChild(georgeVI);
georgeVI.addRoyalChild(elizabethII);
georgeVI.addRoyalChild(margaret);
elizabethII.addRoyalChild(charles);
elizabethII.addRoyalChild(anne);
elizabethII.addRoyalChild(andrew);
elizabethII.addRoyalChild(edward);
charles.addRoyalChild(william);
charles.addRoyalChild(harry);
andrew.addRoyalChild(beatrice);
andrew.addRoyalChild(eugenie);
edward.addRoyalChild(louise);
edward.addRoyalChild(severn);

console.log('georgeV instanceof Royal:', georgeV instanceof Royal);
console.log('elizabethII.totalDescendents: ', elizabethII.totalDescendents);
console.log('typeof Royal: ', typeof Royal);
console.log('Royal.prototype: ', Royal.prototype);
// console.log('georgeV.constructor: ', georgeV.constructor);

console.log('royal with name Beatrice or Harry: ', georgeV.royalWithName('Princess Beatrice', 'Prince Harry'));

У меня острый вопрос: как извлечь объекты из массива, возвращаемого этим методом:

royalWithName(name1, name2) {
    let royals = new Array();
    if (Array.isArray(this.royalChildren)) {
        if ((this.name === name1) || (this.name === name2)) {
            royals.push(this);
        }
        for (let royal of this.royalChildren) {
            let royalsWithMatchingName = new Array();
            royalsWithMatchingName = royal.royalWithName(name1, name2);
            royals = royals.concat(royalsWithMatchingName);
        }
    } else {
        return null;
    }
    return royals;
}

Это узел:

royal with name Beatrice or Harry:  [ Royal {
    name: 'Prince Harry',
    yearBorn: 1984,
    royalParent: 
     Royal {
       name: 'Prince Charles',
       yearBorn: 1948,
       royalParent: [Object],
       royalChildren: [Array] },
    royalChildren: [] },
  Royal {
    name: 'Princess Beatrice',
    yearBorn: 1988,
    royalParent: 
     Royal {
       name: 'Prince Andrew',
       yearBorn: 1960,
       royalParent: [Object],
       royalChildren: [Array] },
    royalChildren: [] } ]

Все, что я хотел бы сделать, это извлечь объекты из массива. (array.length = 0 (-1 + 1?))

Символы, прототипы, итерируемые элементы ... Мне бы очень хотелось, чтобы этот пример был приведен выше. Ссылки будут оценены тоже.

...