如何防止对象数字属性的自动排序?

And*_*yHu 10 javascript sorting properties object

为什么我遇到了这个问题:我试图解决算法问题,我需要返回数组中出现的大部分次数.像[5,4,3,2,1,1]应该返回1.并且当两个数字出现同时作为最大外观返回时,第一个出现.像[5,5,2,2,1]返回5因为5首先出现.我使用一个对象来存储每个数字的外观.关键是数字本身.

所以当输入是[5,5,2,2,1]我的对象应该是, Object {5: 2, 2: 2, 1: 1}但实际上我得到了Object {1: 1, 2: 2, 5: 2} 当我使用for..in迭代对象时,我得到2而不是5.所以这就是我问这个问题的原因.

Chrome控制台中出现此问题,我不确定这是否是一个常见问题:当我运行以下代码时

var a = {};
a[0]=1;
a[1]=2;
a[2]=3;
Run Code Online (Sandbox Code Playgroud)

a是:Object {0: 1, 1: 2, 2: 3}

但是,当我颠倒分配的顺序时:

 var a = {};
 a[2]=3;
 a[1]=2;
 a[0]=1;
Run Code Online (Sandbox Code Playgroud)

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}
Run Code Online (Sandbox Code Playgroud)

这保持了财产秩序.这是解决问题的最佳方法吗?反正有没有阻止这种自动排序行为?这只发生在Chrome V8 JavaScript引擎中吗?先感谢您!

the*_*gie 14

你确实不能依赖 JavaScript 中对象字段的顺序,但如果你需要保留对对象的顺序,我建议使用MapES6/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
Run Code Online (Sandbox Code Playgroud)


Mar*_*elo 10

您正在使用 JS object,根据定义,它不保持顺序。将其视为键 => 值映射。

您应该使用一个array,它将保留您index插入的任何内容。将其视为一个列表。

另请注意,您实际上并没有“反转分配的顺序”,因为您每次都在同一索引上插入元素。


小智 10

target = {}
target[' ' + key] = value // numeric key
Run Code Online (Sandbox Code Playgroud)

这可以防止对象数字属性的自动排序。


小智 6

这是一个古老的话题,但仍然值得一提,因为在一分钟的谷歌搜索中很难找到直接的解释。

\n\n

我最近进行了一次编码练习,查找数组中第一次出现最不频繁/最 频繁的整数,它与您的情况几乎相同。

\n\n

我遇到了和你一样的问题,在 JavaScript 对象中按 ASC 排序数字键,这并没有保留元素的原始顺序,这是 js 中的默认行为。

\n\n

在 ES6 中解决这个问题的更好方法是使用一种新的数据类型:Map

\n\n

Map 可以保留元素(对)的原始顺序,并且还具有对象所具有的唯一键优点。

\n\n
let map = new Map()\nmap.set(4, "first") // Map(1)\xc2\xa0{4 => "first"}\nmap.set(1, "second") // Map(2)\xc2\xa0{4 => "first", 1 => "second"}\nmap.set(2, "third") // Map(3)\xc2\xa0{4 => "first", 1 => "second", 2 => "third"}\nfor(let [key, value] of map) {\n  console.log(key, value)\n}\n// 4 "first"\n// 1 "second"\n// 2 "third"\n
Run Code Online (Sandbox Code Playgroud)\n\n

不过,使用对象数据类型也可以解决问题,但我们需要借助输入数组来取回元素的原始顺序:

\n\n
function findMostAndLeast(arr) {\n  let countsMap = {};\n  let mostFreq = 0;\n  let leastFreq = arr.length;\n  let mostFreqEl, leastFreqEl;\n\n  for (let i = 0; i < arr.length; i++) {\n    let el = arr[i];\n    // Count each occurrence\n    if (countsMap[el] === undefined) {\n      countsMap[el] = 1;\n    } else {\n      countsMap[el] += 1;\n    }\n  }\n\n  // Since the object is sorted by keys by default in JS, have to loop again the original array\n  for (let i = 0; i < arr.length; i++) {\n    const el = arr[i];\n\n    // find the least frequent \n    if (leastFreq > countsMap[el]) {\n      leastFreqEl = Number(el);\n      leastFreq = countsMap[el];\n    }\n\n    // find the most frequent \n    if (countsMap[el] > mostFreq) {\n      mostFreqEl = Number(el);\n      mostFreq = countsMap[el];\n    }\n  }\n\n  return {\n    most_frequent: mostFreqEl,\n    least_frequent: leastFreqEl\n  }\n}\nconst testData = [6, 1, 3, 2, 4, 7, 8, 9, 10, 4, 4, 4, 10, 1, 1, 1, 1, 6, 6, 6, 6];    \nconsole.log(findMostAndLeast(testData)); // { most_frequent: 6, least_frequent: 3 }, it gets 6, 3 instead of 1, 2 \n
Run Code Online (Sandbox Code Playgroud)\n