Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about using array in javascript for web programming

I have to use the directory array in javascript to display directory for the web. But I don't know how to put the condition in this case.

const directory = [
  { type: 'file', name: 'file1.txt' },
  { type: 'file', name: 'file2.txt' },
  {
    type: 'directory',
    name: 'HTML Files',
    files: [
      { type: 'file', name: 'file1.html' },
      { type: 'file', name: 'file2.html' }
    ]
  },
  { type: 'file', name: 'file3.txt' },
  {
    type: 'directory',
    name: 'JavaScript Files',
    files: [
      { type: 'file', name: 'file1.js' },
      { type: 'file', name: 'file2.js' },
      { type: 'file', name: 'file3.js' }
    ]
  }
];

The part I am writing but I don't know how to check the condition since all types all file:

  var File = '\0';
    if ()
    directory.forEach(eachFile => {
      
      File = File + `<li>${eachFile}</li>`;
    });

and this is my HTML file.

 <div id="directories">
          <header>
            <title>File Directories</title>
          </header>
          <body>
            <h2>Directories</h2>
            <ul id = "displayDirectories"></ul>
          </body>
        </div>

And this is how output should be:

image of the output html to achieve

like image 453
Javascript Question Avatar asked Jun 18 '26 21:06

Javascript Question


1 Answers

Since there are multiple levels of the structure, this has to be done recursively, and for that you need a function (that recursively calls itself for each level). The function is simple, it takes a files array and generate the html code (including the <ul> and </ul>) for that array of files, for each item it creates an li element containing the name of that item, if that item is also a directory it calls itself with that directory files array to generate the html of its files and inserts it into the li:

function listEntries(files) {                                              // takes an array of files and generate an html string of the ul element
  let html = "<ul>";                                                       // opening the ul element

  files.forEach(entry => {                                                 // for each entry in the array
    if(entry.type == "file") {                                             // if the entry is a file
      html += "<li>" + entry.name + "</li>";                               // simply add an li element containing the name
    } else {                                                               // otherwise, if it's a directory
      html += "<li>" + entry.name + listEntries(entry.files) + "</li>";    // add an li element containing the name and an ul element of its children, created via calling listEntries on the files array
    }
  });

  return html + "</ul>";                                                   // close the ul and return
}

You can simplify it further by using a reduce instead of forEach and a ternary instead of if/else like so:

function listEntries(files) {
  return files.reduce((html, entry) =>
    html + "<li>" + entry.name + (entry.type === "directory" ? listEntries(entry.files) : "") + "</li>"
  , "<ul>") + "</ul>";
}

Note: Since the ul tags are included in the html, the DOM element that should receive the generated html should not be another ul element, a div will do, like so:

<div id="displayDirectories"></div>

Demo:

function listEntries(files) {
  return files.reduce((html, entry) =>
    html + "<li>" + entry.name + (entry.type === "directory" ? listEntries(entry.files) : "") + "</li>"
  , "<ul>") + "</ul>";
}


const directory = [ { type: 'file', name: 'file1.txt' }, { type: 'file', name: 'file2.txt' }, { type: 'directory', name: 'HTML Files', files: [ { type: 'file', name: 'file1.html' }, { type: 'file', name: 'file2.html' } ] }, { type: 'file', name: 'file3.txt' }, { type: 'directory', name: 'JavaScript Files', files: [ { type: 'file', name: 'file1.js' }, { type: 'file', name: 'file2.js' }, { type: 'file', name: 'file3.js' } ] } ];

document.getElementById("displayDirectories").innerHTML = listEntries(directory);
<div id="displayDirectories"></div>
like image 105
ibrahim mahrir Avatar answered Jun 20 '26 11:06

ibrahim mahrir