Map和Set有什么区别?

66

JavaScript 中的 MapSet 对象都是 可迭代对象。它们都通过 [key, value] 键值对存储对象。

什么时候使用哪一个?它们之间有什么区别?


1
这是一篇很好的文章,讲解得非常清楚:http://2ality.com/2015/01/es6-maps-sets.html - vsync
7个回答

84
只要你谈论的是ES6类型,即使Set可能使用Map实现,它们也不是相同的数据结构。
您对Map的定义是正确的,但是Set是一个包含唯一值的集合,不像数组可以有重复项。
var array = [1, 2, 3, 3];

var set = new Set(array); // Will have [1, 2, 3]
assert(set.size, 3);

var map = new Map();
map.set('a', 1);
map.set('b', 2);
map.set('c', 3);
map.set('C', 3);
map.set('a', 4); // Has: a, 4; b, 2; c: 3, C: 3
assert(map.size, 4);

43
值得明确指出的是,一个 Set 并不是一个键值存储容器,并且与数组不同的是,它没有顺序。 - Ryan Quinn
8
在Map()中,键可以是任何类型[String、Number、Object],但在普通对象中,键必须是字符串类型。 - Pushker Yadav
3
Set是一维的唯一数组,而Map是二维的,具有键值对,其中键必须是唯一的。 - user2513697

29

摘要:

  • 当您的数据集需要由唯一值组成时,请使用Set
  • 当您有成对的关联数据时,请使用Map。您将键映射到值。

Set示例:

与来自不同组织的人进行会议。 一些人来自同一个组织。 我们需要列出所有不同的组织。 为此,我们可以使用Set,因为我们只想包含每个组织一次:

const organization = new Set();

organization.add('org1');
organization.add('org2');
organization.add('org3');
organization.add('org1');
organization.add('org3');
organization.add('org1');

for(let org of organization){
  console.log(org);
}

示例 Map:

我们有一群狗,想要为每只狗分配年龄。我们希望将每只狗的唯一名称映射到狗的年龄:

const dogs = new Map([['fluffy', 10], ['barkie', 13]]);

dogs.forEach((value, key) => console.log(key, value));

MapObject有何不同?

Object也是一个键值对集合,可以完成与Map相同的任务(即创建键值对)。但是,MapObject之间存在一些关键区别:

  • Map内置Iterable,这使得它可以使用for of循环或其实现的forEach()方法,而普通JSObject无法使用。
  • Map在其prototype上具有一些不错的内置方法,可以让您很好地使用它。因为所有Objects都继承自Object.prototype,所以它可以访问更多有用的方法。例如,Map上的size()方法返回Map中键的数量。

19
var obj = {};
obj.name= "Anand Deep Singh";
console.log(obj.name); //logs "Anand Deep Singh"

同样地,在 ES6 中,我们可以使用普通对象。

var map = new Map();
map.set("name","Anand Deep Singh");
console.log(map.get("name")); //logs "Anand Deep Singh"

但值得注意的是,Map并不是使用字面对象语法创建的,而是使用setget方法来存储访问数据

它有一个has方法来检查对象中是否存在该键,delete方法用于删除对象,clear方法用于清空整个对象。

Set是一组唯一的值。它只是一个唯一的列表。

var set = new Set(["a", "a","e", "b", "c", "b", "b", "b", "d"]);
console.log(set); //logs Set {"a", "e", "b", "c", "d"}

Set无法像数组一样被访问,它提供了与Map相同的方法。


5
开发人员通常在需要使用映射时使用普通的 JavaScript 对象。您能详细说明一下这一点吗? - Emobe
一切都取决于您的需求以及解决问题的实现方式。通常,我使用数组或对象字面量来保存任何数据。我很少同时使用两者,因此一切都取决于您的选择 :) - Anand Deep Singh
2
我不会将“当开发者需要使用映射时,通常只使用普通的JavaScript对象”作为答案标题进行宣传。虽然使用对象而不是Map可能是有道理的,但并非总是如此(正如您已经指出的那样)。这样的陈述可能会导致新的JS开发人员养成错误的习惯。请删除该标题并使您的答案更加明确。 - Mak
1
我更新了答案。尽管在我写下这个回复的时候,这不是很常见的事情,所以我才写了那样的话。还是谢谢你提醒我(: - Anand Deep Singh

4

现在主要有两种数据结构:

  • 对象: 用于存储键值对的集合。
  • 数组: 用于存储有序集合。

但这还不够适用于实际生活中的需求。这就是为什么Map和Set也存在的原因。

  • Map: 是一个键值对数据项的集合,与Object类似。但主要区别是Map允许任何类型的键。

例如:

let map = new Map();

map.set('1', 'str1');   // a string key
map.set(1, 'num1');     // a numeric key
map.set(true, 'bool1'); // a boolean key


let hamid = { name: "Hamid" };
// hamid is the key for the map
map.set(hamid, 123); // an object key
  • 集合(Set):是一种特殊类型的集合,它是“值的集合”(没有键),每个值只能出现一次。

示例:

let set = new Set();

let hamid= { name: "Hamid" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };

// visits, some users come multiple times
set.add(hamid);
set.add(pete);
set.add(mary);
set.add(hamid);
set.add(mary);

// set keeps only unique values
alert( set.size ); // 3
 

https://javascript.info/map-set


1
一个集合永远不会有重复的元素,它由唯一的值组成。无论你重复多少次写入相同的值,集合只会保留其中一个。例如:
const colorsSet = new Set([
  'orange',
  'orange',
  'purple',
  'pink',
  'pink',
  'pink',
]); 
// here we have 2 oranges, 3 pinks and 1 purple, but since SETS can NOT have duplicates we will get:
// set(3) {'orange', 'purple', 'pink'})

console.log(colorsSet); // this can be proven also by looking at the size of a set

// We can get the size of a set:
console.log(colorsSet.size); // 3

// We can check if a certain element is in a set:
console.log(colorsSet.has('pink')); // If pink is in set, TRUE
console.log(colorsSet.has('white')); // If white is NOT in set, FALSE

// We can add new elements to a set:
colorsSet.add('black');

// We can also delete elements:
colorsSet.delete('purple'); // it must be straight forward names
console.log(colorsSet); // Set(3) {'orange', 'pink', 'black'}

// We can delete all of the elements in the set:
// colorsSet.clear();


//Sets are iterables, so we can loop over them:
for (const color of colorsSet) console.log(color);

我们可以使用映射将值与键关联起来,而且我们可以使用任何数据类型,但是集合基本上只是一组唯一的值。在我看来,映射比集合更有用。你可以将它们结合使用。例如:
const map = new Map(); // we create an empty map
// to fill up the map we can use SETS

map.set('nameOfFriend', 'locationOfFriend');
map.set('Alicia', 'NYC')
console.log(map.set('Alex", "Washington')); // if you call the set method, it will return the map. 

// Map(3) {'nameOfFriend' => 'locationOfFriend', 'Alicia' => 'NYC', 'Alex' => 'Washington'}

0
Map() 中,键可以是任何类型 [字符串、数字、对象],但常规对象必须是字符串。 Set 是一个具有唯一键的一维数组,而 Map 是一个具有键值对的二维数组,其中每个键都应该是唯一的。
对于 Map(),我们允许使用其他原始类型(包括 NaN)。因此,开发人员能够链接到其他类型的数据。 Set 由一组唯一值组成,而 Map 是将键映射到值时形成的一对关联数据。Map 和 Set 都有类似的方法,例如 .has()、.get()、.delete() 和 .size()。
区别在于 map 具有键值对和两个维度。可以将两个二维数组和数组转换为集合。 总之,Map 用于键值对集合,而 Set 用于唯一值集合。

-1
如果您有想要放入集合中的唯一值,那么您应该使用Set,因为它是用于唯一值的。 否则,如果您不介意有2个或更多相同的值,则应该选择Map。

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接