Помогите решить задачу по js, нужно найти поврежденные файлы и сложить их в массив для дальнейшего анализа

Поврежденные файлы. Раньше в папке хранились разные файлы и поддиректории. Файлы назывались file и использовалась собственная асинхронная файловая система, которая базировалась на объекте Folder c двумя методами:

type File = string | Folder | {} | null | undefined;  
 
type Folder = {  
  // Получить по индексу файл или папку  
  read(index: number, callback: (file: File) => void): void;  
 
  // Получить количество элементов в директории  
  size(callback: (size: number) => void): void;  
} 

Часть файлов осталась без повреждений, часть — потеряна навсегда, потому что превратилась в null или {}, а еще часть повреждена и, кажется, может быть восстановлена. Понять, что файл поврежден очень просто — часть букв в названии продублировались. Помогите найти все такие файлы и сложить их в массив для дальнейшего анализа. Массив надо отсортировать лексиграфически.

Формат ввода Объект с определенной структурой:

Folder([  
    ’file’,  
    ’ffffile’,  
    Folder([  
        ’file’,  
    ]),  
    Folder([  
        ’fiiile’,  
    ]),  
    Folder([  
        {},  
        null,  
        ’file’,  
        ’ffiillee’,  
        ’ffiillee’,  
    ]),  
    Folder([  
        Folder([  
            ’filllle’,  
            ’file’,  
            null,  
        ]),  
        {},  
        Folder([]),  
    ]),  
]);

Формат вывода Массив строк, отсортированный в лексикографическом порядке:

[  
    ’ffffile’,  
    ’ffiillee’,  
    ’ffiillee’,  
    ’fiiile’,  
    ’filllle’,  
]

Примечания

Задачу требуется решить на JavaScript (ES2017) и оформить решение по шаблону:

module.exports = async function(input) {  

    return result;  
}

условия задачи:

((global) => {
    const timeout = 20;

    const _async = (fn, cb) => {
        setTimeout(() => {
            cb(fn());
        }, Math.random() * timeout);
    };

    const Folder = function (a = []) {
        if (!new.target) {
            return new Folder(a);
        }

        this.read = (index, cb) => _async(() => a[index], cb);
        this.size = (cb) => _async(() => a.length, cb);
    };

    Object.freeze(Folder);
    global.Folder = Folder;
})(typeof window === 'undefined' ? global : window);

const input = Folder([
    'file',
    'ffffile',
    Folder([
        'file',
    ]),
    Folder([
        'fiiile',
    ]),
    Folder([
        {},
        null,
        'file',
        'ffiillee',
        'ffiillee',
    ]),
    Folder([
        Folder([
            'filllle',
            'file',
            null,
        ]),
        {},
        Folder([])
    ]),
]);

console.log(input)

// проверка решения
solution(input).then(result => {
    const answer = ['ffffile', 'ffiillee', 'ffiillee', 'fiiile', 'filllle'];
    const isEqual = String(answer) === String(result);

    if (isEqual) {
        console.log('OK');
    } else {
        console.log('WRONG');
    }
});

async function solution(input) {
    // ... решение задачи

    // пример вызова read
    input.read(1, (file) => console.log(file));

    // пример вызова size
    input.size((size) => console.log(size));
}


Ответы (1 шт):

Автор решения: Aziz Umarov

Оформлением займетесь сами. Я помогу решить простую задачу.

//тупо мок объект для проверки
let Folder = function(optionsArray) {  
   return optionsArray;
} 

const input = Folder([
    'file',
    'ffffile',
    Folder([
        'file',
    ]),
    Folder([
        'fiiile',
    ]),
    Folder([
        {},
        null,
        'file',
        'ffiillee',
        'ffiillee',
    ]),
    Folder([
        Folder([
            'filllle',
            'file',
            null,
        ]),
        {},
        Folder([])
    ]),
]);

//воспользуемся примером https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
function flatten(array) {
  var flattend = [];
  (function flat(array) {
    array.forEach(function(el) {
      if (Array.isArray(el)) flat(el);
      else flattend.push(el);
    });
  })(array);
  return flattend;
}


// проверка удовлетворяет ли имя файла нашим условиям
function isRecoverable(fileName) {
    for(var key in fileName) {
        // проверка существует ли собственное свойство key у объекта
        // по существу просто проверка не пустой ли объект {} 
        if(fileName.hasOwnProperty(key))
        {
          // объект не пустой нужно проверить на дубликаты букв
          // тут возможно и другое решение, но я выбрал это   
          return fileName.length != [...new Set(...fileName.split())].length;
        }
    }
    return false;
}

// также отсортировать
let result = flatten(input).filter(file => isRecoverable(file)).sort();

console.log(result);

→ Ссылка