Как вызвать рекурсивный вызов наконец, если он удовлетворяет условию?

#javascript #reactjs #typescript #algorithm #data-structures

#javascript #reactjs #typescript #алгоритм #структуры данных

Вопрос:

У меня есть вложенный объект с именем option. Он имеет вложенные (потенциально бесконечные) объекты, называемые childOptions key .

 option = {
  name: 'o1', label: 'o1', childOptions: [
    { name: 'o4', label: 'o4', childOptions: [
      {name: 'o5', label: 'o5',
    ]},
    { name: 'o2', label: 'o3'},
    { name: 'o3', label: 'o3'}
  ]
}
  

Это моя функция рендеринга для рендеринга JSX на основе этого.

   function renderOption(option): JSX.Element {
    if (option.childOptions) {
      return (
        <li
          key={option.name}
        >
          <span>
            {option.label}
          </span>
          <ul>
            {option.childOptions.map(renderOption} << recursive call!
          </ul>
        </li>
      );
    }
  

У меня есть вложенный option объект, который переходит в renderOption

Это текущий вывод (ПРАВИЛЬНЫЙ, но не то, что я хочу)

 <li>
  <span>o1</span>
  <ul>
    <li>
      <span>o4</span>
      <ul>
        <li><span>o5</span></li>
      <ul>
    </li>
    <li><span>o2</span></li>
    <li><span>o3</span></li>
  </ul>    
</li>
  

Поскольку мы показываем o2 и o5 сразу после o1, пользователь запутывается при чтении.
Это то, что мне нужно

 <li>
  <span>o1</span>
  <ul>
    <li><span>o2</span></li>
    <li><span>o3</span></li>
    <li>
      <span>o4</span>
      <ul>
        <li><span>o5</span></li>
      <ul>
    <li>
  </ul>    
</li>
  

Я думаю, что это может быть невозможно. Как мы вызываем рекурсивный вызов наконец, если он удовлетворяет условию?

  • Я все еще хочу сохранить рекурсивный вызов, если бы мы могли.

Комментарии:

1. o2 В option объекте нет

2. Выходные данные, которыми вы поделились, не соответствуют входным данным. В вашем коде есть несбалансированная скобка.

3. извините, ребята; редактирование…

4. Это исправлено; извините. Я думаю, что это запуталось при обработке и вставке

5. Несбалансированная фигурная скобка в вашем первом блоке. Пожалуйста … найдите время, чтобы опубликовать правильный код.

Ответ №1:

Сортировка childOptions в вашем объекте по имени:

   function renderOption(option): JSX.Element {
    if (option.childOptions) {

      option.childOptions.sort((a, b) => a.name.localeCompare(b.name));

      return (
        <li
          key={option.name}
        >
          <span>
            {option.label}
          </span>
          <ul>
            {option.childOptions.map(renderOption} << recursive call!
          </ul>
        </li>
      );
    }
  

Комментарии:

1. холли Краб гений

Ответ №2:

Вы могли бы вернуть a ul для массива опций. Получите массив опций в качестве реквизита для компонента функции. Передайте исходный option объект в виде массива, чтобы сделать его единообразным и упростить выполнение рекурсивного вызова

Вот выполняемый фрагмент:

 const option={name:"o1",label:"o1",childOptions:[{name:"o4",label:"o4",childOptions:[{name:"o5",label:"o5"}]},{name:"o2",label:"o2"},{name:"o3",label:"o3"}]};

function Display({ options }) {
  return (
    <ul>
      {options.map(c => (
        <li key={c.name}>
          <span>{c.label}</span>
          {c.childOptions amp;amp; <Display options={c.childOptions} />}
        </li>
      ))}
    </ul>
  );
}

ReactDOM.render(
  <Display options={[option]} />, 
  document.getElementById("root")
);  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>