.flat() не является функцией, что не так?

Следующий код

function steamrollArray(arr) {
  // I'm a steamroller, baby
  return arr.flat();
}

steamrollArray([1, [2], [3, [[4]]]]);

возвращается

arr.flat не является функцией

Я попробовал это в Firefox и Chrome v67, и результат был тот же.

Что случилось?


person TechnoKnight    schedule 22.06.2018    source источник
comment
Его экспериментальный. Какой у вас браузер?   -  person Phix    schedule 22.06.2018
comment
Какой браузер? Вы смотрели таблицу доступности?   -  person zero298    schedule 22.06.2018
comment
Да, я видел это и пробовал в Firefox, когда это не сработало, я попробовал еще раз в Chrome (который поддерживается, последняя версия), и результат тот же.   -  person TechnoKnight    schedule 22.06.2018
comment
Какую версию Chrome вы используете?   -  person chuckx    schedule 22.06.2018
comment
@TechnoKnight Chrome 69+ поддерживается. Какая у вас версия Хрома?   -  person    schedule 22.06.2018
comment
Ой, у меня 67 версия, лол.   -  person TechnoKnight    schedule 22.06.2018
comment
Могу я кое-что спросить, а как насчет консоли freecodecamp, она связана с браузером или нет?   -  person TechnoKnight    schedule 22.06.2018
comment
хром 69 даже не выпущен как стабильный   -  person baao    schedule 22.06.2018
comment
Он также доступен только в Firefox Nightly, как, опять же, говорится в документации по MDN.   -  person Sebastian Simon    schedule 22.06.2018
comment
О чувак! Это означает, что мне придется писать код вручную, вздох. Что ж, спасибо вам большое!   -  person TechnoKnight    schedule 22.06.2018
comment
@TechnoKnight Подробности, подробности. :) В качестве альтернативы вы можете либо реализовать метод самостоятельно, либо использовать один из библиотек, таких как Lodash: lodash.com/docs/4.17.10#flattenDeep   -  person    schedule 22.06.2018
comment
Я просто создам метод сам. Спасибо всем за помощь! И извините, что ввел вас в заблуждение, сказав, что у меня последняя версия Хрома, ну я думал, что у меня последняя версия (похоже, что 69 не стабильная, просто бета)   -  person TechnoKnight    schedule 22.06.2018
comment
Я добавил ответ ниже, пожалуйста, посмотрите.   -  person Ivan    schedule 22.06.2018


Ответы (6)


Метод flat еще не реализован в обычных браузерах (только Chrome v69, Firefox Nightly и Opera 56). Это экспериментальная функция. Поэтому вы не можете использовать его пока.

Вместо этого вы можете захотеть иметь свою собственную функцию flat:

Object.defineProperty(Array.prototype, 'flat', {
    value: function(depth = 1) {
      return this.reduce(function (flat, toFlatten) {
        return flat.concat((Array.isArray(toFlatten) && (depth>1)) ? toFlatten.flat(depth-1) : toFlatten);
      }, []);
    }
});

console.log(
  [1, [2], [3, [[4]]]].flat(2)
);

Код был взят из здесь автором Noah Freitas изначально реализован для выравнивания массива без указания depth.

person Ivan    schedule 22.06.2018
comment
Это было бы эквивалентно arr.flat(Infinity), но не с аргументом по умолчанию 1. - person Patrick Roberts; 22.06.2018
comment
@Ivan flat принимает один аргумент который определяет глубину выравнивания. Этот полифилл не работает. - person Sebastian Simon; 22.06.2018
comment
Спасибо, что указали на это, я отредактировал свой ответ, теперь это работает правильно? - person Ivan; 22.06.2018
comment
Просто запустите фрагмент кода, чтобы проверить его. Ваш 4 все еще находится в массиве. - person Matt; 22.06.2018
comment
@Matt Так и должно быть (результат [1,2,3,[4]] в Chrome v69). - person Ivan; 22.06.2018
comment
вы можете не использовать depth-1 в качестве своего условия, если вы передадите 0, это станет -1, что равно true, а не false. - person WORMSS; 03.04.2019
comment
@WORMSS, спасибо, что заметили ошибку, я ее исправил, заменив условие на depth > 1. - person Ivan; 03.04.2019
comment
@RotimiBest Это странно. Я проверил, и он работает на Chrome v74. Можете попробовать ввести Array.prototype.flat в консоли? - person Ivan; 10.05.2019
comment
В конце 2019 года flat() больше не является экспериментальным и поддерживается во всех современных браузерах (поэтому везде, кроме IE и Edge… и он появится в Edge, когда в ближайшем будущем он переключится на движок рендеринга Blink). - person Quentin; 13.11.2019
comment
сентябрь 2020 г., все еще проблема :/ - person Ambroise Rabier; 12.09.2020

Это тоже может сработать.

let arr = [ [1,2,3], [2,3,4] ];
console.log([].concat(...arr))

Или для старых браузеров,

[].concat.apply([], arr);
person R.Cha    schedule 13.03.2020
comment
Очень просто, у меня работал тест на Leetcode, так как array.flat() не поддерживался в JS - person cherucole; 11.05.2020

Array.flat не поддерживается ваш браузер. Ниже приведены два способа его реализации.

В качестве функции переменная depth указывает, насколько глубоко структура массива input должна быть сплющена (по умолчанию 1; используйте Infinity, чтобы углубляться настолько глубоко, насколько это возможно), в то время как stack представляет собой сглаженный массив, который передается по ссылке при рекурсивных вызовах и в конечном итоге возвращается.

function flat(input, depth = 1, stack = [])
{
    for (let item of input)
    {
        if (item instanceof Array && depth > 0)
        {
            flat(item, depth - 1, stack);
        }
        else {
            stack.push(item);
        }
    }
    
    return stack;
}

Как Polyfill, расширение Array.prototype, если вы предпочитаете синтаксис arr.flat():

if (!Array.prototype.flat)
{
    Object.defineProperty(Array.prototype, 'flat',
    {
        value: function(depth = 1, stack = [])
        {
            for (let item of this)
            {
                if (item instanceof Array && depth > 0)
                {
                    item.flat(depth - 1, stack);
                }
                else {
                    stack.push(item);
                }
            }
            
            return stack;
        }
    });
}
person resu    schedule 29.08.2019
comment
понятия не имею, почему flat не работает в моем узле v12, в любом случае спасибо за flat func, скопируйте и получите то, что мне нужно ‹3 - person Yegor Zaremba; 08.03.2020

используйте _.flatten из пакета lodash;)

person Bash Lord    schedule 08.02.2020

Аналогичная проблема, решенная с помощью метода ES6 .reduce():

const flatArr = result.reduce((acc, curr) => acc.concat(curr),[]);
person irina    schedule 28.01.2021

Не уверен, что это правильный ответ, однако в своей попытке сгладить массив я использовал destructuring_assignment появился в ES6.

// typeScriptArray:Array<Object> = new Array<Object>();
let concatArray = [];

let firstArray = [1,2,3];
let secondArray = [2,3,4];

concatArray.push(...firstArray);
concatArray.push(...secondArray);

console.log(concatArray);

Это работает как шарм, хотя я не уверен, могут ли возникнуть какие-либо проблемы с совместимостью браузера.

person giannis christofakis    schedule 14.05.2019
comment
Вы можете просто сделать concatArray = [...firstArray, ...secondArray] - person georg; 14.05.2019
comment
@georg, так даже лучше. - person giannis christofakis; 14.05.2019