JavaScript 递归识别最后一个元素

JavaScript Recursion identify last element

我这里有一段代码,我想识别最后一个元素 paragraph 3 并添加一些文本,例如 - last item,输出将是 paragraph 3 - last item.

我希望它是递归的,因为 object.

中的数字 children 没有限制
obj = {
    content: [
        { text: "paragraph 1" },
        { 
            content: [
                { text: "paragraph 2" },
            ]
        },
        { text: "paragraph 3" },
    ]
}

另一个例子是这个,它的输出应该是paragraph 5 - last item

obj = {
    content: [
        { text: "paragraph 1" },
        { 
            content: [
                { text: "paragraph 2" }
            ]
        },
        { text: "paragraph 3" },
        { 
            content: [
                { text: "paragraph 4" },
                { 
                    content: [
                        { text: "paragraph 5" }
                    ]
                }
            ]
        }
    ]
}

一种方法是循环并在一个变量中获取对 text 的引用,并在每个循环中更新它。在所有循环结束后,变量将指向最后一个 text,因此您只需向其添加 ' - last item'

这是一个工作示例:

const obj1 = {
  content: [{
      text: 'paragraph 1'
    },
    {
      content: [{
        text: 'paragraph 2'
      }]
    },
    {
      text: 'paragraph 3'
    },
    {
      content: [{
          text: 'paragraph 4'
        },
        {
          content: [{
            text: 'paragraph 5'
          }]
        },
      ],
    },
  ],
}

const obj2 = {
  content: [{
      text: 'paragraph 1'
    },
    {
      content: [{
        text: 'paragraph 2'
      }]
    },
    {
      text: 'paragraph 3'
    },
  ],
}

let last

function getLast(o) {
  for (let key in o) {
    if (o[key] instanceof Array) {
      for (let value of o[key]) {
        getLast(value)
      }
    } else if (key == 'text') {
      last = o
    }
  }
}

getLast(obj1)
last.text += ' - last item'
getLast(obj2)
last.text += ' - last item'

console.log('\nobj1 = ', JSON.stringify(obj1, null, 1))
console.log('\nobj2 = ', JSON.stringify(obj2, null, 1))

编辑:如果您真正想要的只是获取最后一项的文本,那么您也可以这样做:

const obj1 = {
  content: [{
      text: 'paragraph 1'
    },
    {
      content: [{
        text: 'paragraph 2'
      }]
    },
    {
      text: 'paragraph 3'
    },
    {
      content: [{
          text: 'paragraph 4'
        },
        {
          content: [{
            text: 'paragraph 5'
          }]
        },
      ],
    },
  ],
}

const obj2 = {
  content: [{
      text: 'paragraph 1'
    },
    {
      content: [{
        text: 'paragraph 2'
      }]
    },
    {
      text: 'paragraph 3'
    },
  ],
}


let last
function getLast(o) {
  for (let key in o) {
    if (o[key] instanceof Array) {
      for (let value of o[key]) {
        getLast(value)
      }
    } else if (key == 'text') {
      last = o
    }
  }
  return last.text
}

const last1 = getLast(obj1)
console.log(last1)
const last2 = getLast(obj2)
console.log(last2)

一个简单的实现。检查键名,如果它是内容,它会用最后一个元素重新调用。否则,它将 return 它。

const obj1 = {
  content: [{
    text: "paragraph 1"
  }, {
    content: [{
      text: "paragraph 2"
    }]
  }, {
    text: "paragraph 3"
  }]
};

const obj2 = {
  content: [{
      text: "paragraph 1"
    },
    {
      content: [{
        text: "paragraph 2"
      }]
    }, {
      text: "paragraph 3"
    },
    {
      content: [{
          text: "paragraph 4"
        },
        {
          content: [{
            text: "paragraph 5"
          }]
        }
      ]
    }
  ]
}

function getLatestParagraph(obj) {
  for (const key in obj) {
    if (key === "content") return getLatestParagraph(obj[key].pop());
    return obj[key];
  }
}

console.log(getLatestParagraph(obj1))
console.log(getLatestParagraph(obj2))

您可以映射 content 属性 和 return 中的每个元素。如果 content 属性 存在,相同的条件将再次 运行,否则它将打印 text 属性.

let lastItem = {};

function recursive(node) {
    if (node.content) {
        node.content.map(element => recursive(element));
    } else if (node.text) {
        lastItem = node.text;
    }
}

obj.content.map(node => recursive(node));
console.log(lastItem + " - last item");

工作演示:https://jsfiddle.net/4f7Lt3ue/

这是一个递归解决方案,它采用内容中的最后一项,只要有一个,或者只是 returns 当前对象的文本:

const obj1 = {"content":[{"text":"paragraph 1"},{"content":[{"text":"paragraph 2"}]},{"text":"paragraph 3"}]};
const obj2 = {"content":[{"text":"paragraph 1"},{"content":[{"text":"paragraph 2"}]},{"text":"paragraph 3"},{"content":[{"text":"paragraph 4"},{"content":[{"text":"paragraph 5"}]}]}]}

const getLatestParagraph = obj => 
  !obj.content?.at(-1) // if there isn't a last item in content
  ? obj.text // return the current text
  : getLatestParagraph(obj.content.at(-1)) // or run the function on the new last item

console.log(getLatestParagraph(obj1))
console.log(getLatestParagraph(obj2))