javascript 如何防止对象数字属性的自动排序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33351816/
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
How to prevent automatic sort of Object numeric property?
提问by AndyHu
Why I met this problem: I tried to solve an algorithm problem and I need to return the number which appeared most of the times in an array. Like [5,4,3,2,1,1] should return 1. And also when two number appear same time as the maximum appearance return the one came first. Like [5,5,2,2,1] return 5because 5appear first. I use an object to store the appearance of each number. The key is the number itself.
为什么我会遇到这个问题:我试图解决一个算法问题,我需要返回数组中大部分时间出现的数字。像 [5,4,3,2,1,1] 应该返回 1。而且当两个数字与最大出现次数同时出现时,返回第一个。像 [5,5,2,2,1] 返回5因为5首先出现。我使用一个对象来存储每个数字的外观。关键是数字本身。
So When the input is [5,5,2,2,1] my object should be
Object {5: 2, 2: 2, 1: 1}
but actually I got Object {1: 1, 2: 2, 5: 2}
So When I use for..in to iterate the object I got 2returned instead of 5. So that's why I asked this question.
因此,当输入为 [5,5,2,2,1] 时,我的对象应该是
Object {5: 2, 2: 2, 1: 1}
但实际上我得到了Object {1: 1, 2: 2, 5: 2}
所以当我使用 for..in 迭代对象时,我返回了2而不是5。所以这就是我问这个问题的原因。
This problem occurs in Chrome console and I'm not sure if this is a common issue: When I run the following code
这个问题出现在 Chrome 控制台中,我不确定这是否是一个常见问题:当我运行以下代码时
var a = {};
a[0]=1;
a[1]=2;
a[2]=3;
ais: Object {0: 1, 1: 2, 2: 3}
一个是:Object {0: 1, 1: 2, 2: 3}
But when I reverse the order of assignment like:
但是当我颠倒分配顺序时:
var a = {};
a[2]=3;
a[1]=2;
a[0]=1;
ais also:Object {0: 1, 1: 2, 2: 3}
The numeric property automatic sorted in ascending order.
I tried prefix or postfix the numeric property like
a也是:Object {0: 1, 1: 2, 2: 3}
数字属性自动按升序排序。我试过前缀或后缀数字属性,如
var a = {};
a['p'+0]=1;
a['p'+1]=2;
a['p'+2]=3;
console.log(a);//Object {p0: 1, p1: 2, p2: 3}
And this keep the property order. Is this the best way to solve the problem? And is there anyway to prevent this auto sort behavior? Is this only happen in Chrome V8 JavaScript engine? Thank you in advance!
这保持了财产秩序。这是解决问题的最佳方法吗?无论如何要防止这种自动排序行为?这只发生在 Chrome V8 JavaScript 引擎中吗?先感谢您!
采纳答案by Marcelo
You are using a JS object
, that by definition does not keep order. Think of it as a key => value map.
您正在使用 JS object
,根据定义,它不会保持秩序。将其视为键 => 值映射。
You should be using an array
, that will keep whatever you insert on the index
you inserted it into. Think of it as a list.
您应该使用array
, 它将保留您插入的任何index
内容。把它想象成一个列表。
Also notice that you did notin fact "reverse the order of the assignment", because you inserted elements on the same index every time.
另请注意,您实际上并没有“颠倒分配的顺序”,因为您每次都在同一索引上插入元素。
回答by 201709071716
target = {}
target[' ' + key] = value // numeric key
This can prevent automatic sort of Object numeric property.
这可以防止对象数字属性的自动排序。
回答by Brad Kent
instead of generating an object like {5: 2, 2: 2, 1: 1}
而不是生成一个对象 {5: 2, 2: 2, 1: 1}
generate an array to the effect of
生成一个数组的效果
[
{key: 5, val: 2},
{key: 2, val: 2},
{key: 1, val: 1}
]
or... keep track of the sort order in a separate value or key
或者...在单独的值或键中跟踪排序顺序
回答by theVoogie
You really can't rely on order of an object fields in JavaScript, but I can suggest to use Map(ES6/ES2015 standard) if you need to preserve order of your key, value
pair object. See the snippet below:
您真的不能依赖 JavaScript 中对象字段的顺序,但如果您需要保留配对对象的顺序,我可以建议使用Map(ES6/ES2015 标准)key, value
。请参阅下面的片段:
let myObject = new Map();
myObject.set('z', 33);
myObject.set('1', 100);
myObject.set('b', 3);
for (let [key, value] of myObject) {
console.log(key, value);
}
// z 33
// 1 100
// b 3
回答by cyianite
I've stumbled with this issue with our normalised array which keyed with Ids> After did my research, I found out there's no way to fix using the object keys because by default the Javascript is sorting any object key with number when you iterate it.
我在使用 Ids> 键控的规范化数组时偶然发现了这个问题。经过我的研究,我发现无法使用对象键进行修复,因为默认情况下,Javascript 会在您迭代时使用数字对任何对象键进行排序。
The solution I've done and it worked for me is to put a 'sortIndex' field and used that to sort the list.
我已经完成并且对我有用的解决方案是放置一个“sortIndex”字段并用它来对列表进行排序。
回答by Linming Ye
This is an old topic but it is still worth mentioning as it is hard to find a straight explanation in one-minute googling.
这是一个古老的话题,但仍然值得一提,因为在一分钟的谷歌搜索中很难找到直接的解释。
I recently had a coding exercise that finding the first occurrenceof the least/mostfrequentinteger in an array, it is pretty much the same as your case.
我最近有一个编码练习,找到第一次出现的最小/最常见的数组中的整数,它几乎是一样的你的情况。
I encountered the same problem as you, having the numeric keys sorted by ASC in JavaScript object, which is not preserving the original order of elements, which is the default behavior in js.
我遇到了和你一样的问题,JavaScript对象中的数字键按ASC排序,没有保留元素的原始顺序,这是js中的默认行为。
A better way to solve this in ES6 is to use a new data type called: Map
在 ES6 中解决这个问题的更好方法是使用一种新的数据类型:Map
Map can preserve the original order of elements(pairs), and also have the unique key benefit from object.
Map 可以保留元素(对)的原始顺序,并且还具有对象的唯一键优势。
let map = new Map()
map.set(4, "first") // Map(1)?{4 => "first"}
map.set(1, "second") // Map(2)?{4 => "first", 1 => "second"}
map.set(2, "third") // Map(3)?{4 => "first", 1 => "second", 2 => "third"}
for(let [key, value] of map) {
console.log(key, value)
}
// 4 "first"
// 1 "second"
// 2 "third"
However, using the object data type can also solve the problem, but we need the help of the input array to get back the original order of elements:
不过,使用对象数据类型也可以解决问题,但是我们需要借助输入数组来找回元素的原始顺序:
function findMostAndLeast(arr) {
let countsMap = {};
let mostFreq = 0;
let leastFreq = arr.length;
let mostFreqEl, leastFreqEl;
for (let i = 0; i < arr.length; i++) {
let el = arr[i];
// Count each occurrence
if (countsMap[el] === undefined) {
countsMap[el] = 1;
} else {
countsMap[el] += 1;
}
}
// Since the object is sorted by keys by default in JS, have to loop again the original array
for (let i = 0; i < arr.length; i++) {
const el = arr[i];
// find the least frequent
if (leastFreq > countsMap[el]) {
leastFreqEl = Number(el);
leastFreq = countsMap[el];
}
// find the most frequent
if (countsMap[el] > mostFreq) {
mostFreqEl = Number(el);
mostFreq = countsMap[el];
}
}
return {
most_frequent: mostFreqEl,
least_frequent: leastFreqEl
}
}
const testData = [6, 1, 3, 2, 4, 7, 8, 9, 10, 4, 4, 4, 10, 1, 1, 1, 1, 6, 6, 6, 6];
console.log(findMostAndLeast(testData)); // { most_frequent: 6, least_frequent: 3 }, it gets 6, 3 instead of 1, 2
回答by Marcos Mendes
I came across this same problem, and after search a lot about that, i found out that the solution to prevent this behavior is make key as string.
我遇到了同样的问题,经过大量搜索后,我发现防止这种行为的解决方案是将密钥设为字符串。
Like that:
像那样:
{"a": 2, "b": 2}
回答by bhavinjr
simply do that while you're working with a numeric array index
只需在使用数字数组索引时执行此操作
data = {}
data[key] = value