如何在Javascript中获得真实的地图和集合
How to get real maps and sets in Javascript?
Javascript是一种简洁的语言,但似乎缺乏一些非常基本的功能,如映射和集合。
Map是一个键/值存储区,其中键和值可以是任意对象,每个键最多有一个值,通过严格的相等来区分。
Set与映射相同,只是它没有值,并且您只对存在感兴趣,同样是严格相等。
如果我想使用这些ADT,我们在javascript中最接近的是Object,它几乎是正确的,但将所有键强制为字符串,这使得它对一些实际集和映射将用于的事情毫无用处。
给定映射,集合是平凡的:set[key] = true
而不是set[key] = value
。或者可以用Arrays、Array.indexOf和Array.splice实现全集功能(对于小集)。添加并行值列表将提供映射功能。对于较大的数据集,可以在普通对象之上实现哈希表,但我认为这将成为一个更严肃的项目。
因此,我的问题是,是否有比上述建议更惯用的实现(或更简单的解决方案)来从Javascript中获得完整的Map/Set功能?还是每个人都对此忍气吞声?
编辑所以看起来es6地图/集规范是可行的。我会接受一个链接到/显示简单可用垫片的答案。
不幸的是,在Javascript中无法做到这一点。
然而
似乎没有比在OP中咬紧牙关地提出建议更惯用的解决方案了。然而,正如其他贡献者所指出的,映射和集合正在ES6中出现,并且有一个可执行规范。
ES6可执行规范使用了OP中建议的映射实现,并在此基础上实现了集合;映射是作为一个键阵列和一个vals阵列完成的,与array.splice和线性扫描保持平行。不幸的是,它似乎使用了一些在主流JS中不可接受的深奥语法。
为了给我们提供一个可用的填充程序,我获取了链接的规范,经过一些修改将其转换为coffeescript,并编写了一些测试来演示功能。代码在我的github:上
#A non-stupid alternative to Array.prototype.indexOf
indexOfIdentical = (keys, key) ->
for i of keys
if keys[i] == key
return i
return -1
class Map
constructor: (a = []) ->
@keys = [];
@vals = [];
for [k,v] in a
@set k, v
get: (key) ->
i = indexOfIdentical @keys, key
return if i < 0 then undefined else @vals[i]
has: (key) ->
return 0 <= indexOfIdentical @keys, key
set: (key, val) ->
i = indexOfIdentical @keys, key
if i < 0
i = @keys.length
@keys[i] = key
@vals[i] = val
del: (key) ->
i = indexOfIdentical @keys, key
if i < 0
return false
@keys.splice i, 1
@vals.splice i, 1
return true
class Set
constructor: (a = []) ->
@keys = []
for key in a
@add key
has: (key) ->
return 0 <= indexOfIdentical @keys, key
add: (key) ->
i = indexOfIdentical @keys, key
if i < 0
i = @keys.length
@keys[i] = key
del: (key) ->
i = indexOfIdentical @keys, key
if i < 0
return false
@keys.splice i, 1
return true
#this is implemented as a simple node.js module:
#include with mapset = require("./path/to/mapset.js")
module.exports = {Map: Map, Set: Set}
不,没有但是Javascript对象是最接近集合和映射的表示。
以下是它们的不同使用方式:
var foo = {]
// The following two are the same thing.
foo.bar = true;
foo['bar'] = true;
var bar = 'bar';
foo[bar] = true; // again, the same thing.
或
var foo = { bar: true }
它们可以很容易地迭代:
for (item in foo) {
if (foo.hasOwnProperty[item]) {
console.log(item); // --> returns 'bar';
console.log(foo[item]); // --> returns true;
}
}
检查属性的存在:
if (foo[bar] !== undefined) {
// ... it doesn't
}
// If one declares a property without any value,
foo.bar;
//It will still come out as undefined
console.log(foo.bar); // --> undefined
- 谷歌地图固定位置覆盖
- 不显示带有本地json文件数据的谷歌地图脚本
- 谷歌地图不是以HTML显示,而是在JS Fiddle上工作
- 谷歌地图标记不会显示
- 无法在JS中显示谷歌地图
- 科尔多瓦页面类应用程序中的多个谷歌地图
- 需要帮助谷歌地图方向面板在FancyBox中显示
- 是否可以控制获取哪些Google地图脚本(JavaScript API)
- 在谷歌地图上获取事件的x,y坐标
- 谷歌地图API v3不适用于移动浏览器或PhoneGap
- 模拟谷歌地图中的点击
- 如何知道哪个标记被谷歌地图点击了
- 谷歌地图JS API+JSON-多个标记没有显示
- 缓存谷歌地图数据
- 谷歌地图劫持了iphone's滚动(触摸事件)-如何恢复
- 单击超链接时,如何使用Google Maps API v3缩放地图
- 在谷歌地图上绘制位置数据库
- 如何使用jquery将base64图像路径转换为真实路径
- 标记的实时更新,无需加载页面谷歌地图API V3
- 如何在Javascript中获得真实的地图和集合