Как кодировать «идентификатор метода DOM для использования в рекурсии»? - PullRequest
0 голосов
/ 10 марта 2020

У меня проблема в getObjectById для использования в рекурсии. Выполнение функции getObject(data, '11') ---> undefined. Я не знаю, почему это происходит: undefined.

В функции getObject(data, '1'~'9') ---> Я получил решение. Но '11' ,'12', '13', '14' ---> undefined

Для решения этой проблемы мне нужно использовать forEach, Array.prototype.apply, но я не могу ее решить.

Использование filter ---> TypeError: Cannot read property 'filter' of undefined

Использование length ---> TypeError: Cannot read property 'length' of undefined

В первой строчке у меня есть проблема, которую нужно решить. Во второй строке я написал код для решения этой проблемы. Как мне кажется, я объясняю свою логику c решению проблемы. Но в тестовом случае это не удалось.

Решение этой проблемы:

let output = getObjectById(TREE_DATA.items, '1'))

console.log(output) --> { "id": "1", "name": "johnny" }
    --in first under line, 
    let TREE_DATA = {
      items: [
        {
          id: "1",
          name: "johnny"
        },
        {
          id: "2",
          name: "ingi",
          children: [
            {
              id: "3",
              name: "johnson"
            },
            {
              id: "4",
              name: "katy"
            },
            {
              id: "5",
              name: "steve",
              children: [
                {
                  id: "6",
                  name: "lisa"
                },
                {
                  id: "7",
                  name: "penny",
                  children: [
                    {
                      id: "8",
                      name: "john"
                    },
                    {
                      id: "9",
                      name: "hoyong"
                    }
                  ]
                },
                {
                  id: "10"
                }
              ]
            },
            {
              id: "11"
            },
            {
              id: "12"
            }
          ]
        },
        {
          id: "13"
        },
        {
          id: "14"
        }
      ]
    };

    --in second under line,

    function getObject(json, id) {
      let test = json.items;
      let newA = [];

      function getA(a, id) {
        a.filter(function(e) {
          console.log("this is : ", e);
          if (e.id && e.id === id) {
            return newA.push(e);

          } else if (e.id !== id && e.children) {
            return getA(e.children, id);
          }
        });
      }

      getA(test, id);
      return newA[0];
    }

Ответы [ 2 ]

1 голос
/ 10 марта 2020

Поскольку ваши входные данные являются рекурсивной структурой, программа с рекурсивной структурой будет наилучшим совпадением. В этом случае у вас есть -

  • a список из узлов (TREE_DATA.items)
  • , где каждый узел ( объект ) может содержать children свойство , которое также является списком из узлов

Это рекурсивное отношение дает нам уникальную возможность узнать об особом виде рекурсии, когда одна функция, A , вызывает функцию B , которая, в свою очередь, вызывает функцию A , который вызывает B и так далее ... это называется взаимная рекурсия .

Мы начинаем с функции, которая занимает всего one входных узлов, метко названных find1. Он принимает один узел, деструктурированный до children и o, и идентификатор для поиска, id -

const find1 = ({ children = [], ...o }, id = 0) =>
  o.id == id                 // if the object's id matches the input id,
    ? o                      // match found! return the object
    : findAll(children, id)  // otherwise findAll of the children with the id

Далее очевидно, что нам нужно реализовать findAll. Он принимает список узлов, деструктурированных до first и more, и идентификатор для поиска, id -

const findAll = ([ first, ...more ], id = 0) =>
  first === undefined        // if the list is empty,
    ? undefined              // there's nothing to search! return no match
    : find1(first, id)       // find1 the first item in the list using the id
      || findAll(more, id)   // OR findAll on more using the same id

Вот и все! Функции почти пишут сами, без необходимости в посторонних переменных или шагах. Он ведет себя точно так, как мы ожидаем -

console.log(findAll(TREE_DATA.items, 1))
// { id: "1", name: "johnny" }

console.log(findAll(TREE_DATA.items, 11))
// { id: "11" }

console.log(findAll(TREE_DATA.items, 99))
// undefined (no match found)

Проверьте результаты в своем браузере, запустив фрагмент ниже -

const find1 = ({ children = [], ...o }, id = 0) =>
  o.id == id
    ? o
    : findAll(children, id)

const findAll = ([ first, ...more ], id = 0) =>
  first === undefined
    ? undefined
    : find1(first, id) || findAll(more, id)

const TREE_DATA =
    {items:[{id:"1",name:"johnny"},{id:"2",name:"ingi",children:[{id:"3",name:"johnson"},{id:"4",name:"katy"},{id:"5",name:"steve",children:[{id:"6",name:"lisa"},{id:"7",name:"penny",children:[{id:"8",name:"john"},{id:"9",name:"hoyong"}]},{id:"10"}]},{id:"11"},{id:"12"}]},{id:"13"},{id:"14"}]}

console.log(findAll(TREE_DATA.items, 1))
// { id: "1", name: "johnny" }

console.log(findAll(TREE_DATA.items, 11))
// { id: "11" }

console.log(findAll(TREE_DATA.items, 99))
// undefined (no match found)
0 голосов
/ 10 марта 2020

Это то, что вы ищете?

let TREE_DATA = {
  items: [
    {
      id: "1",
      name: "johnny"
    },
    {
      id: "2",
      name: "ingi",
      children: [
        {
          id: "3",
          name: "johnson"
        },
        {
          id: "4",
          name: "katy"
        },
        {
          id: "5",
          name: "steve",
          children: [
            {
              id: "6",
              name: "lisa"
            },
            {
              id: "7",
              name: "penny",
              children: [
                {
                  id: "8",
                  name: "john"
                },
                {
                  id: "9",
                  name: "hoyong"
                }
              ]
            },
            {
              id: "10"
            }
          ]
        },
        {
          id: "11"
        },
        {
          id: "12"
        }
      ]
    },
    {
      id: "13"
    },
    {
      id: "14"
    }
  ]
};

function getObject(json, id) {
  let test = json.items;
  let newA = [];

  function getA(a, id) {
    a &&
      a.forEach(function(e) {
        if (e.id === id) {
          newA.push(e);
        } else if (e.children) {
          getA(e.children, id);
        }
      });
  }

  getA(test, id);
  return newA[0];
}

function getObjectById(items, key) {
  let ret = {};

  for (let item of items) {
    if (item.id === key) {
      return item;
    }
    if (item.children) {
      let innerRet = getObjectById(item.children, key);
      if (Object.keys(innerRet).length) return innerRet;
    }
  }

  return ret;
}

console.log("2", getObjectById(TREE_DATA.items, "2"));
console.log("3", getObjectById(TREE_DATA.items, "3"));
console.log("11", getObjectById(TREE_DATA.items, "11"));
console.log("12", getObjectById(TREE_DATA.items, "12"));
console.log("13", getObjectById(TREE_DATA.items, "13"));

console.log("2", getObject(TREE_DATA, "2"));
console.log("3", getObject(TREE_DATA, "3"));
console.log("11", getObject(TREE_DATA, "11"));
console.log("12", getObject(TREE_DATA, "12"));
console.log("13", getObject(TREE_DATA, "13"));

Редактировать: отлажена и добавлена ​​ваша функция.

...