Как конвертировать набор в массив?

469

Set кажется хорошим способом создания массивов с гарантированно уникальными элементами, но он не предоставляет никакого хорошего способа получения свойств, за исключением генератора [Set] .values, который вызывается неудобным образом mySet.values.next().

Это было бы хорошо, если бы вы могли вызывать mapи подобные функции на множествах. Но вы также не можете этого сделать.

Я пытался Array.from, но, похоже, конвертирует только массивы (NodeList и TypedArrays?) Объектов в массив. Еще одна попытка: Object.keysне работает для Sets, а Set.prototype не имеет аналогичного статического метода.

Итак, вопрос: есть ли удобный встроенный метод для создания массива со значениями данного набора? (Порядок элементов не имеет большого значения).

если такой опции не существует, то, возможно, есть хорошая идиоматическая строчка для этого? как, используя for...of, или подобное?

C69
источник

Ответы:

851

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

Действительно, есть несколько способов преобразовать Set в массив :

с помощью Array.from

let array = Array.from(mySet);

Просто spreadingРазместите в массиве

let array = [...mySet];

Старый способ, итерация и передача в новый массив (наборы есть forEach)

let array = [];
mySet.forEach(v => array.push(v));

Ранее, с использованием нестандартного, а теперь и устаревшего синтаксиса понимания массива:

let array = [v for (v of mySet)];
adeneo
источник
7
Это не работает в Safari (8) или Chrome (41). Но это работает в Firefox (35).
155
2
var array = [v for (v of mySet)];не работает в chrome 46
Эрик
18
Я думаю, что самый элегантный способ это просто [...mySet].
Войцех Беднарски
18
@WojciechBednarski l33t не элегантно . Если какой-то из примеров Array.from(mySet);
Буффало
3
Просто хотел добавить, что [...mySet]есть проблемы при компиляции с использованием Typescript (см. Эту проблему ), поэтому, вероятно, безопаснее использовать, Array.from(mySet)если вы собираетесь конвертировать в Typescript в ближайшем будущем.
Иван Гозали
65

через https://speakerdeck.com/anguscroll/es6-uncensored Ангусом Кроллом

Оказывается, мы можем использовать spreadоператор:

var myArr = [...mySet];

Или, альтернативно, используйте Array.from:

var myArr = Array.from(mySet);
C69
источник
1
почему отрицательный голос? Есть ли проблемы с этим подходом? Или кто-то пытался выполнить этот код в IE11 и потерпел неудачу ? ;)
c69
6
Я не понизил голос, но я попробовал это в последней версии Chrome и потерпел неудачу, так что это не просто проблема IE.
Мешааль
3
обратитесь к kangax.github.io/compat-table/es6 для получения более или менее актуальной диаграммы поддержки. В настоящее время из всех настольных браузеров поддерживается только FF и IE TP (он же Spartan, он же браузер MS Non-IE) Array.fromи...
c69
Похоже, Firefox - единственный браузер, который поддерживает Array.from. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
425nesp
1
Здесь вы можете включить его для Chrome. chrome://flags/#enable-javascript-harmonyПомните, что это экспериментально, не думайте, что это хорошее решение для разработки.
Соспедра
12

Предполагая, что вы просто Setвременно используете уникальные значения в массиве, а затем конвертируете обратно в массив, попробуйте использовать это:

_.uniq([])

Это зависит от использования подчеркивания или черточки .

fremn
источник
К сожалению, единственное перекрестное решение
Marco Sulla
6

Возможно, чтобы опоздать на вечеринку, но вы могли бы просто сделать следующее:

const set = new Set(['a', 'b']);
const values = set.values();
const array = Array.from(values);

Это должно работать без проблем в браузерах, которые поддерживают ES6, или если у вас есть прокладка, которая правильно заполняет вышеуказанные функции.

Изменить : Сегодня вы можете просто использовать то, что предлагает @ c69:

const set = new Set(['a', 'b']);
const array = [...set]; // or Array.from(set)
Roland
источник
1
Кажется, что с помощью set.entries()вы получите массив пар. Вы можете использовать, set.values()чтобы получить простой массив.
Шимон Рахленко
@ShimonRachlenko правда, и пользователь действительно просил об этом.
Роланд
2
Вы можете просто использоватьvar array = Array.from(set);
Буффало
этот ответ просто неверен. Вам не нужно звонить .entries, ни .values. Как упомянуто выше @Buffalo - Array.from(set)достаточно.
с69
1
@ c69 это правда. На момент этого ответа Array.from()не получилось, как ожидалось. Но теперь выкладываю и Array.from()оба работают просто отлично.
Роланд
4

Используйте спред оператора, чтобы получить желаемый результат

var arrayFromSet = [...set];
Виньеш Муруган
источник
0

В моем случае решение было:

var testSet = new Set();
var testArray = [];

testSet.add("1");
testSet.add("2");
testSet.add("2"); // duplicate item
testSet.add("3");

var someFunction = function (value1, value2, setItself) {
    testArray.push(value1);
};

testSet.forEach(someFunction);

console.log("testArray: " + testArray);

значение1 равно значению2 => Значение, содержащееся в текущей позиции в наборе. Для обоих аргументов передается одинаковое значение

Работал под IE11.

d0wn
источник
0

Использование Set и преобразование его в массив очень похоже на копирование массива ...

Таким образом, вы можете использовать те же методы для копирования массива, что очень легко в ES6

Например, вы можете использовать ...

Представьте, что у вас есть этот сет ниже:

const a = new Set(["Alireza", "Dezfoolian", "is", "a", "developer"]);

Вы можете просто конвертировать его используя:

const b = [...a];

и результат:

["Alireza", "Dezfoolian", "is", "a", "developer"]

Массив и теперь вы можете использовать все методы, которые вы можете использовать для массива ...

Другие распространенные способы сделать это:

const b = Array.from(a);

или используя такие циклы:

const b = [];
a.forEach(v => b.push(v));
Алиреза
источник
0

Код ниже создает набор из массива и затем, используя ...оператор.

var arr=[1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,];
var set=new Set(arr);
let setarr=[...set];
console.log(setarr);
Экрам Маллик
источник
Пожалуйста, прокомментируйте свой код.
Хима
1
.. а это что?
ZF007
-1

Вот простой способ получить только уникальные необработанные значения из массива. Если вы преобразуете массив в Set и после этого выполните преобразование из Set в массив. Это преобразование работает только для необработанных значений, для объектов в массиве оно недопустимо. Попробуйте сами.

    let myObj1 = {
        name: "Dany",
        age: 35,
        address: "str. My street N5"
    }

    let myObj2 = {
        name: "Dany",
        age: 35,
        address: "str. My street N5"
    }

    var myArray = [55, 44, 65, myObj1, 44, myObj2, 15, 25, 65, 30];
    console.log(myArray);

    var mySet = new Set(myArray);
    console.log(mySet);

    console.log(mySet.size === myArray.length);// !! The size differs because Set has only unique items

    let uniqueArray = [...mySet];
    console.log(uniqueArray); 
    // Here you will see your new array have only unique elements with raw 
    // values. The objects are not filtered as unique values by Set.
    // Try it by yourself.
zdrsoft
источник
-1

ПРОСТО ОТВЕТ

просто разложите набор внутри []

let mySet = new Set()
mySet.add(1)
mySet.add(5)
mySet.add(5) 
let arr = [...mySet ]

Результат : [1,5]

Алджон Ямаро
источник