javascript 排序映射实现
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14645035/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sorted Map Implementation
提问by Chris
My Task
我的任务
In my JavaScript code i'm often using objects to "map" keys to values so i can later access them directly through a certain value. For example:
在我的 JavaScript 代码中,我经常使用对象将键“映射”到值,以便我以后可以通过某个值直接访问它们。例如:
var helloMap = {};
helloMap.de = "Hallo";
helloMap["en"] = "Hello";
helloMap.es = "Hola";
So i build up the map object step by step in my source code using the two available notations object styleand array style.
因此,我使用两种可用的符号object style和array style在我的源代码中逐步构建地图对象。
Later i can then access the values i added through helloMap["de"]
for example. So thats all fine if i don't have to care about the order in which the attributes has been set on the object.
稍后我可以访问我添加的值helloMap["de"]
,例如。因此,如果我不必关心在对象上设置属性的顺序,那一切都很好。
If i want to iterate the objects properties now as far as i know there is no way to ensure that i'll iterate them in the order they have been added.
如果我现在想迭代对象属性,据我所知,没有办法确保我会按照添加的顺序迭代它们。
Note:I can't use some wrapper object and simply hold a array in there and then use its methods to add the values so something like this:
注意:我不能使用一些包装器对象并简单地在其中保存一个数组,然后使用其方法添加值,如下所示:
var HelloMap = function(){
this.myMap = [];
this.addProperty = function(key, value){
this.myMap.push({key: key, value: value});
}
}
or something similar won't work for me. So the solution needs to be absolutely transparent to the programmer using the object.
或类似的东西对我不起作用。所以解决方案需要对使用对象的程序员绝对透明。
That said the object i needed would be an empty object which maintains the order of the properties that were added to it. Something like this would do:
也就是说,我需要的对象将是一个空对象,它维护添加到它的属性的顺序。像这样的事情会做:
var helloMap = {};
helloMap = getOrderAwareObject(helloMap);
so that every further assignment of the form helloMap.xy = "foo"
and helloMap["yz"] = "bar"
would be tracked in the object "in order",
使得每个以下形式的进一步分配helloMap.xy = "foo"
和helloMap["yz"] = "bar"
将在对象被跟踪“按顺序”,
Possible Solutions
可能的解决方案
Since i did not find any solution in underscore or jQuery giving me such a special object i came across the possibility of defining getters and setters for properties in JavaScript objects with Object.defineProperty
since i can rely on ECMAScript 5standard i can use it.
由于我没有在下划线或 jQuery 中找到任何解决方案给我这样一个特殊的对象,我遇到了为 JavaScript 对象中的属性定义 getter 和 setter 的可能性,Object.defineProperty
因为我可以依赖ECMAScript 5标准,我可以使用它。
The Problem with this one is, that you have to know all the possible properties that can be set on the object, before they are actually set. Since if you defineit you got to nameit.
这个的问题是,在实际设置之前,您必须知道可以在对象上设置的所有可能的属性。因为如果你定义它,你必须命名它。
What i am searching for is something like a Default Getterand Default Setterwhich applies on the object if no getter and setter has been defined for the property. So i could then hide the sorted mapbehind the object inteface.
如果没有为属性定义 getter 和 setter,我正在搜索的是类似Default Getter和Default Setter 的东西。因此,我可以将排序后的映射隐藏在对象界面后面。
- Is there already a solution for this in any framework you know?
- Is there a mechanism like "default getter/setter" ?
- 在您知道的任何框架中是否已经有解决方案?
- 有没有像“默认的getter/setter”这样的机制?
回答by Tim Down
You'll need a wrapper of some kind using an array internally, I'm afraid. ECMAScript 5 (which is the standard on which current browser JavaScript implementations are based) simply doesn't allow for ordered object properties.
恐怕您需要在内部使用数组的某种包装器。ECMAScript 5(这是当前浏览器 JavaScript 实现所基于的标准)根本不允许有序的对象属性。
However, ECMAScript 6 will have a Map
implementationthat has ordered properties. See also http://www.nczonline.net/blog/2012/10/09/ecmascript-6-collections-part-2-maps/.
但是,ECMAScript 6 将有一个具有有序属性的Map
实现。另见http://www.nczonline.net/blog/2012/10/09/ecmascript-6-collections-part-2-maps/。
There may also be other options in ECMAScript 6. See the following question:
ECMAScript 6 中可能还有其他选项。请参阅以下问题:
How can I define a default getter and setter using ECMAScript 5?
回答by factotum
Adding a link to a custom javascript library which provides Sorted maps and other implementation, for future reference in this thread . Check out https://github.com/monmohan/dsjslib-msingh
添加指向自定义 javascript 库的链接,该库提供 Sorted maps 和其他实现,以供将来在此线程中参考。查看https://github.com/monmohan/dsjslib-msingh
回答by Beetroot-Beetroot
I don't know of a general solution but non-general solutions are very simple to construct.
我不知道通用解决方案,但非通用解决方案构建起来非常简单。
Typically, you maintain an Array of objects, with several methods defined as properties of the Array. At least, that's my approach.
通常,您维护一个对象数组,其中有几个方法定义为数组的属性。至少,这是我的方法。
Here's an example, taken (in a modified form) from a larger application :
这是一个示例,取自一个更大的应用程序(以修改的形式):
var srcs = [];
srcs.find = function(dist) {
var i;
for(i=0; i<this.length; i++) {
if(dist <= this[i].dist) { return this[i]; }
}
return null;
};
srcs.add = function(dist, src) {
this.push({ dist:dist, src:src });
}
srcs.remove = function(dist) {
var i;
for(i=0; i<this.length; i++) {
if(this[i].dist === dist) {
srcs.splice(i,1);
return true;
}
}
return false;
};
srcs.add(-1, 'item_0.gif' );
srcs.add(1.7, 'item_1.gif');
srcs.add(5, 'item_2.gif');
srcs.add(15, 'item_3.gif');
srcs.add(90, 'item_4.gif');
Unfortunately, you lose the simplicity of a plain js object lookup, but that's the price you pay for having an ordered entity.
不幸的是,您失去了普通 js 对象查找的简单性,但这就是您为拥有有序实体付出的代价。
If you absolutely must have order and dot.notation, then maintain a plain js Object for lookup andan Array for order. With care, the two can be maintained with total integrity.
如果您绝对必须有订单和 dot.notation,那么维护一个普通的 js 对象用于查找和一个 Array 用于订单。小心,两者可以保持完全的完整性。
回答by Jared Smith
回答by Amit Sharma
var put = function(k,v){
if(map[k]){
console.log("Key "+ k+" is already present");
}else
{
var newMap = {};
map[k] = v;
Object.keys(map).sort().forEach(function(key){
newMap[key] = map[key];
});
map = newMap;
//delete newMap; in case object memory need to release
return map;
}
}
Put method will always take a key-value pair, internally creates another map with sorted keys from the actual map, update the value and return the updated map with sorted keys.No external library need to includ.
Put 方法将始终采用键值对,在内部使用实际映射中的排序键创建另一个映射,更新值并返回带有排序键的更新映射。不需要包含外部库。