Сведение и сортировка массива массивов JavaScript

первоначально опубликовано на hellodevworld.com

365 дней программирования день 2! Как сглаживать, фильтровать, сортировать и массивировать в JavaScript. Решение для популярного вопроса на собеседовании сглаживает массив, сделанный еще на один шаг вперед, чтобы сделать его массивом только с уникальными значениями и отсортировать его в числовом порядке. Я добавил строки в тесты позже сегодня, поэтому прошу прощения у людей, которые ранее получили только цифры. для их испытаний.

Отказ от ответственности: есть МНОГИЕ способы решить эту проблему, это ответы, которые я увижу или использую на собеседовании по программированию и приму как правильный ответ.

TLDR: объяснение решения внизу сообщения

Проблема

Напишите функцию, которая принимает массив чисел или строк, это может быть массив с любым количеством вложенных массивов. Сгладьте массив (сделайте все на одном уровне), поместите его в числовой порядок различных чисел из исходного массива.

Примеры:

flattenFilterAndSort([1, 1, 6, 9])  //[1, 6, 9]   
    flattenFilterAndSort([20, [3, 5], 10])  //[3, 5, 10, 20]   
    flattenFilterAndSort([[1,2,3],[[4,5],6,[7,8,9], 19, 21, [0, 1], ]])  //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 19, 21]
    flattenFilterAndSort(['Marv', ['Dakota', 'Boo'], 'Dakota']) //['Boo', 'Dakota', 'Marv']
    flattenFilterAndSort(['Happy', [['New'], ['Year']]]) //["Happy", "New", "Year"]

Решение

Для этого нам понадобится рекурсивная функция. Рекурсивная функция — это функция, которая вызывает сама себя. Если вы не знакомы с рекурсией и хотели бы узнать о ней больше, загляните на эту страницу.

Итак, давайте сломаем, что нам нужно сделать

  • создать функцию, которая принимает и массив
  • создать новый массив для хранения всего
  • цикл по переданному массиву
  • проверить, является ли текущий индекс массивом
  • если это массив
  • если это только одноуровневый массив, объедините этот массив с текущим массивом
  • в противном случае вызовите flattenFilterAndSort еще раз, чтобы выполнить те же проверки — рекурсия здесь
  • если не нажать текущий индекс на новый массив и продолжить цикл
  • как только цикл закончился
  • отфильтровать цикл, чтобы были только уникальные значения
  • отсортировать эти значения

Сначала нам нужно создать функцию

function flattenFilterAndSort(arr){
    // create a new array to hold everything
    // loop through the passed array
        // check if the current index is an array
            // if its an array 
               // if its only a single level array concatenate that array with the current array
              // otherwise call flattenFilterAndSort again to do the same checks - recursion is here
          // if not push the current index to the new array and continue the loop
    // once loop has ended
        // filter the loop to be only unique values
       // sort those values
}

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

function flattenFilterAndSort(arr){
    let flatArray = []
    // loop through the passed array
        // check if the current index is an array
            // if its an array 
                // if its only a single level array concatenate that array with the current array
               // otherwise call flattenFilterAndSort again to do the same checks - recursion is here
          // if not push the current index to the new array and continue the loop
    // once loop has ended
        // filter the loop to be only unique values
       // sort those values
}

теперь нам нужно перебрать массив, который был передан. Если вы не знакомы с циклами for, посетите эту страницу W3Schools.

function flattenFilterAndSort(arr) {
    let flatArray = [];
    for(var i = 0; i < arr.length; i++) {
        // check if the current index is an array
            // if its an array 
                // if its only a single level array concatenate that array with the current array
               // otherwise call flattenFilterAndSort again to do the same checks - recursion is here
          // if not push the current index to the new array and continue the loop
    // once loop has ended
        // filter the loop to be only unique values
       // sort those values
    }
}

Теперь нам нужно проверить, является ли текущий индекс массивом. Если вы не знакомы с .isArray(), посетите эту страницу MDN.

function flattenFilterAndSort(arr) {
    let flatArray = [];
    for(var i = 0; i < arr.length; i++) {
         if(Array.isArray(arr[i])) {
            // if its an array 
                // if its only a single level array concatenate that array with the current array
               // otherwise call flattenFilterAndSort again to do the same checks - recursion is here
         } else {
          // if not push the current index to the new array and continue the loop
         }
    // once loop has ended
        // filter the loop to be only unique values
       // sort those values
    }
}

А теперь самое интересное. Если вы не знакомы с .concat(), проверьте эту страницу MDN, прежде чем двигаться дальше.

Если вы используете .concat() для массива, он объединит этот массив с массивом, который вы объединяете, сделав его одним плоским массивом. Это означает, что нам нужно объединить новый массив с любым массивом, с которым мы можем столкнуться. Однако сначала нам нужно проверить, есть ли в этих массивах также вложенные массивы (нам нужно перебирать эти массивы так же, как и первый массив), это когда вступает в действие рекурсия. Поэтому для каждого массива, с которым мы сталкиваемся, мы собираемся вызвать ту же функцию, которую мы уже вызывали, чтобы убедиться, что эти массивы сведены. Как только массивы станут плоскими, мы будем объединять их, пока все массивы не будут объединены, и у нас не будет 1 плоского массива. Рекурсия будет выглядеть так:

function flattenFilterAndSort(arr) {
    let flatArray = [];
    for(var i = 0; i < arr.length; i++) {
         if(Array.isArray(arr[i])) {
            flatArray = flatArray.concat(flattenFilterAndSort(arr[i]));
         } else {
          // if not push the current index to the new array and continue the loop
         }
    // once loop has ended
        // filter the loop to be only unique values
       // sort those values
    }
}

Это может показаться немного запутанным, поскольку мы устанавливаем плоский массив в пустой массив в начале функции, поэтому каждый раз, когда мы рекурсивно просматриваем его, мы устанавливаем его в []. Вы должны помнить, хотя это происходит рекурсивно. Он ничего не конкатенирует, пока массивы не станут плоскими. Таким образом, он перебирает только тот массив, в котором мы сейчас находимся, а не те, что были до него. Каждый раз, когда он достигает плоского массива, он объединяет его с массивом, который был до него. Итак, представьте, что он сначала находит самый вложенный массив, затем объединяет его с предыдущим и так далее, и так далее, пока все не станет одним уровнем, а затем объединяет его с исходным плоским массивом. Если это не имеет смысла, попробуйте поместить журнал консоли в строку 6 (сразу после flatArray = flatArray.concat(flatten(arr[i]))) как только у вас будет окончательный ответ, и вы сможете увидеть, какой плоский массив находится в каждом цикле это может иметь больше смысла для вас вот пример:

если это не массив, то все, что нам нужно сделать, это поместить его в плоский массив так, как он есть. Если вы не знакомы с .push(), вы можете проверить эту страницу MDN.

function flattenFilterAndSort(arr) {
    let flatArray = [];
    for(var i = 0; i < arr.length; i++) {
        if(Array.isArray(arr[i])) {
            flatArray = flatArray.concat(flattenFilterAndSort(arr[i]));
        } else {
            flatArray.push(arr[i]);
        }
    }
      // once loop has ended
        // filter the loop to be only unique values
       // sort those values
}

Мы должны отфильтровать сглаженный массив. Вы можете сделать это с помощью .filter(), однако я собираюсь распространить flatArray на новый набор, потому что это проще. Если вы не знакомы ни с одним из них, я связал с ними страницы MDN.

function flattenFilterAndSort(arr) {
    let flatArray = [];
    for(var i = 0; i < arr.length; i++) {
        if(Array.isArray(arr[i])) {
            flatArray = flatArray.concat(flattenFilterAndSort(arr[i]));
        } else {
            flatArray.push(arr[i]);
        }
    }
    return [...new Set(flatArray)]
    //sort those values
}

Теперь все, что нам нужно сделать, это отсортировать их. нам нужно сначала проверить, является ли массив массивом строк или массивом чисел, потому что это определит, как нам нужно их сортировать. с числами вы должны указать .sort(), как сортировать их со строками, он автоматически отсортирует их по алфавиту, если вы просто используете .sort(). Если вы не знакомы с этим, загляните на эту страницу MDN

function flattenFilterAndSort(arr) {
    let flatArray = [];
    for(var i = 0; i < arr.length; i++) {
        if(Array.isArray(arr[i])) {
            flatArray = flatArray.concat(flatten(arr[i]));
        } else {
            flatArray.push(arr[i]);
        }
    }
    return typeof(flatArray[0]) === 'string' ? [...new Set(flatArray)].sort() : [...new Set(flatArray)].sort((num1, num2) => {return num1 - num2}) 
}

Ну вот! Опять же, есть много способов написать это. Мне нравится это решение за производительность и удобочитаемость. Если вы хотите получать по электронной почте задачу каждый день утром и уведомление, когда решение опубликовано, подпишитесь ниже. Пожалуйста, оставьте свои решения, которые вы придумали, в разделе комментариев. Если у вас есть какая-либо задача, которую вы хотели бы решить, также оставьте ее в комментариях ниже, вы можете увидеть, как она появится! Если хотите получать задания на почту утром, подписывайтесь здесь!