Checking for files that are mentioned as children of other files I am working in JavaScript on a GruntFile script, and I am creating an object that holds a file class for each one of the following class structure:

class file = {
    path: string,
    name: string,
    children: string[],
    parents: string[],
    packages: string[]
}


I need to loop over each one of these files in the object, and for each one of the files loop over all of the other files and check if their children array contains the current file matching on name.

My coworker and I have come up with multiple solutions to this nasty business.

The first is a more "streamlined" approach, which is believed to "execute faster":

const fileArray = Object.keys(files).map( key =&gt; files[key]);
fileArray.forEach( fileOuter =&gt; fileArray.forEach( fileInner =&gt; { if ( fileInner.children.includes(fileOuter.name)) fileOuter.parents.push(fileInner.name) } ) );


The second solution is clearer:

// Loop over all files by key
Object.keys( files ).forEach( key =&gt; {

    // Get the current file name
    const curFileName = file.name;

    // Loop over all files again
    Object.keys(files).forEach( innerKey =&gt; {

        // Get the inner loop file
        const fileInner = files[innerKey];

        // If the file lists the current file as a dependency
        if ( fileInner.children.indexOf(curFileName) !== -1 ){

            // Push the file name into the parents array for the current file
            files[curFileName].parents.push(fileInner.name);
        }
    })
})


Or if we really wanted to make the loop as fast as possible:

// Get the object keys of the files object
const fileKeys = Object.keys(files);

// Loop over each file
for( var i=0, j=fileKeys.length; i&lt;j; i++){

    // Get the current file name
    const curFileName = files[fileKeys[i]].name;

    // Loop over each file
    for( k=0, k&lt;j, k++){

        // Get the inner file
        const fileInner = files[fileKeys[k]];

        // If the inner files children array matches the current file name, push the inner file name to the current files parents array
        if( fileInner.children.indexOf(curFileName) !== 1 ) files[curFileName].parents.push( fileInner.name );
    }
}


Is any of these methods objectively better than the other? Is there an even better approach we could be taking for this task?
General Remarks

Why are your files assigned to properties of an object? Keeping them in an array would be simpler. Or do you wish to store some kind of mapping from id → file? You currently use the file's name as a unique id which would then redundantly appear on both sides of that mapping.

Matching only by file name seems risky to me, but it really depends on your definition of 'child'. Depending on the exact use case, a file path plus name or a file hash value might be a more suitable unique identifier.

I would avoid talking about 'class structure' when describing the structure of anonymous objects. 'class' has a specific meaning, especially since the class keyword has been introduced to JavaScript now. If your files were really instances of a class, you would probably want to use some kind of creational design pattern such as a factory or factory method which avoids the issue of having to deal with incompletely initialized instances until you finally fill in the parents.


Style

The first code sample could be more readable if it weren't squeezed into a single line.

All code samples could benefit from better naming. Instead of file write child, instead of fileInner write parent, instead of curFileName write child.name etc.

Instead of indexOf use includes. Since you already use const, you should also use let instead of var or globals.

Instead of Object.keys use Object.values.


Your first or second example could be written as:
files.forEach(parent =&gt; {
  files.forEach(child =&gt; {
    if (parent.children.includes(child.name)) {
      child.parents.push(parent.name);
    }
  });
})

Alternatively using for-of-loops:
for (const child of files) {
  for (const parent of files) {
    if (parent.children.includes(child.name)) {
      child.parents.push(parent.name);
    }
  }
}

If files is not an array but an object, replace files with Object.values(files).
Performance
If performance is really an issue, look into the runtime complexity of your operations. By introducing an explicit Map from parent names to children files, the runtime complexity could be reduced to depend linearly on the total number of children only.