У меня есть массив объектов, который выглядит так:
var array = [
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
...
];
Как видите, некоторые имена повторяются. Я хочу получить новый массив только с именами, но если какое-то имя повторяется, я не хочу добавлять его снова. Я хочу этот массив:
var newArray = ["Name1", "Name2"];
Я пытаюсь сделать это с помощью map
:
var newArray = array.map((a) => {
return a.name;
});
Но проблема в том, что это возвращается:
newArray = ["Name1", "Name1", "Name2", "Name2"];
Как я могу установить внутри какое-то условие map
, чтобы оно не возвращало уже существующий элемент? Я хочу сделать это с помощью map
какой-либо другой функции ECMAScript 5 или ECMAScript 6.
javascript
arrays
snoopy25
источник
источник
Set
? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Ответы:
С ES6 вы можете использовать
Set
для уникальных значений после сопоставления только имен объектов.В этом предложении используется синтаксис распространения
...
для сбора элементов в новом массиве.источник
...
?...
для построения массива с итерируемым объектом.Array.from
гораздо лучше передает намерение преобразования (а также его легче понять / найти новичкам), синтаксис распространения следует использовать только там, где распространяемый элемент является одним из многих. Может быть, называть это «плохой практикой» слишком резко, извините, я просто надеюсь, что это не станет распространенной идиомой.Если вы ищете решение JavaScript , что не является ES 6 (не комплект) , вы можете использовать массив в
reduce
метод :источник
var names = array.reduce(function(a, b) { a.indexOf(b.name) === -1 && a.push(b.name) return a; }, []);
Лично я не понимаю, почему всем нравится ES 6. Если бы это был мой код, я бы предпочел поддерживать как можно больше браузеров.
источник
indexOf
-ing? Напр. Делайadded[name] = true
иif(added[name])
вместоif(a.indexOf(name))
.goto fail
, пропускаете свою индексную переменную в охватывающую область и т. д. и т. д. ES6 был кодифицирован в стандарте по уважительным причинам, и для большинства часть тривиально легко полифилить / преобразовывать для старых браузеров.Вы также можете просто комбинировать
map
сfilter
источник
Вы можете использовать Object.keys (), чтобы получить массив имен перечислимых свойств данного объекта из результата перебора
array
переменной с помощью Array.prototype.reduce (), где ключи - это разрушенные имена.Код:
источник
Здесь много хороших ответов. Я просто хотел бы внести свой вклад с некоторым разнообразием в надежде дать вам другую точку зрения.
В JavaScript массивы относятся к объектному типу, поэтому их можно одновременно использовать как хэш. Используя эту функциональность, мы можем значительно упростить работу, которую нужно выполнить за одну операцию сокращения с временной сложностью O (n).
Если вас не устраивает, что ваш массив содержит некоторые свойства, отличные от ключей массива, вы также можете рассмотреть возможность сохранения отдельного хеш-объекта.
источник
p[c.name]
на отдельном объекте,o
а потом отказаться от него.Я согласен с тем, что если вам нужны только
name
ценности, лучше всего использовать aSet
.тем не мение , если вы хотите получить массив уникальных объектов на основе
name
свойства, я бы предложил использовать файлMap
. Быстрый способ создать карту - использовать массив[key, value]
массивов:Дополнительным преимуществом
Map
является то, что вы получаете обеfilter
функции, исключающие неуникальные объекты, без потери связи с исходными объектами. Конечно, это необходимо только в том случае, если вам нужно несколько раз ссылаться на уникальный набор объектов.источник
Если вы ограничены ES5, я бы использовал Lodash's
_.uniq
источник
С ES6 это должно работать.
источник
map
предполагается использовать с чистыми функциями, чтобы не иметь побочных эффектов. Это была бы работа дляforEach
илиreduce
.Используя UnderscoreJS,
`
источник
В ES5 используйте объект в качестве словаря для O ( n ) производительности.
Это будет работать, только если все ключи являются строками.
Вы можете сделать то же самое в одном выражении, если хотите:
но повелительную форму мне легче читать.
источник
function (item) { return item.name; }
Object.keys()
, этот ответ использованийfilter()
сохранить только те имена , которые еще не были сохранены на карте, которая довольно элегантно.Попробуй это:
источник
Использование
array#forEach()
иarray#indexOf()
методы , как это , если вы хотите максимальную совместимость еще, лаконичный синтаксис:Однако, если совместимость не является проблемой использования ECMAScript 6 «s
Set
объекта,array#map
и такиеArray.from()
методы , как это:источник
Вот как я это сделал, используя отдельный пустой массив.
источник
Для тех, кто ищет 1 лайнер
или без использования методов в прототипе массива
может быть полезно для написания некоторых чистых функций для работы с этим
источник
источник