Home > database >  JavaScript Recursion identify last element
JavaScript Recursion identify last element

Time:11-14

I have a piece of code here, and i wanted to identify the last element paragraph 3 and add some text like - last item and the output would be paragraph 3 - last item.

I would prefer if its recursive since there is no limit on the number children in an object.

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

Another example would be this, its output should be paragraph 5 - last item

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

CodePudding user response:

If there's text add it to the output array. If there's content call the function again with the content, and then output array. Grab the last element from the returned data.

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 loop(content, out = []) {
  for (const c of content) {
    if (c.content) loop(c.content, out);
    if (c.text) out.push(c.text);
  }
  return out;
}

console.log(loop(obj1.content).pop());
console.log(loop(obj2.content).pop());
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

One way is to loop and get a reference to text in one variable and update it each loop. After all the loops end the variable will be pointing to tha last text so you just add ' - last item' to it.

Here is a working example:

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))
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Edit: If what you actually wanted is just get the text of the last item then you can also do this:

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)
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related