The short one:
let result = array.reduce((accumulator,c)=>{
!accumulator.find(w=>w.folder_name == c.folder_name)?
accumulator.push({folder_name: c.folder_name, file_name: [c.file_name]}):
accumulator.find(w=>w.folder_name == c.folder_name).file_name.push(c.file_name)
return accumulator
},[])
Using Reduce function makes it easy and readable. Reduce function iterates first parameter (which is a function) as much as the length of array. We pass an empty list as a second parameter to the Reduce function. It is also the accumulator parameter. Reduce function updates the list a.k.a accumulator in every iteration. It means Reduce returns of the previous iteration's accumulator in each one.
e.g: accumulator.push(5) will return a list contains the number 5 as the length of array, because we pushed the number 5 to the list in every iteration.
The parameter c is the current element being processed in the array.
e.g: The first iteration of Reduce gives array[0] in the parameter c, the second one gives array[1], and so on. In this case, c is an object list.
Moreover, we use Conditional Operator in the function we have passed as a first parameter. Conditional Operator is the short version of the If-else statement.
!accumulator.find(w=>w.folder_name == c.folder_name)
We search if the list accumulator contains an object that has the same key-value with the parameter c (which is one of the elements of array - depends on the index of iteration).
If we do not find any folder_name equals to c's one, we push a new object that contains those values
accumulator.push({folder_name: c.folder_name, file_name: [c.file_name]})
If we find any folder_name equals to c's one, we get this object with the help of find and add necessary values to this object
accumulator.find(w=>w.folder_name == c.folder_name).file_name.push(c.file_name)
In conclusion, after checking every c (Current Value) in accumulator and adding necessary values to accumulator in each iteration, we return accumulator. It passes accumulator to the next iteration and at the end, it returns accumulator itself