[英]Is there a way to sort/order keys in JavaScript objects?
例如以下
var data = {
'States': ['NSW', 'VIC'],
'Countries': ['GBR', 'AUS'],
'Capitals': ['SYD', 'MEL']
}
for (var item in data) {
console.log(item);
}
印刷
States
Countries
Capitals
有沒有辦法按字母順序排序以便打印
Capitals
Countries
States
不在對象本身內:對象的屬性集合是無序的。
您可以做的一件事是使用Object.keys()
,並對數組進行排序,然后對其進行迭代。
Object.keys(data)
.sort()
.forEach(function(v, i) {
console.log(v, data[v]);
});
不支持 ECMAScript 第 5 版的瀏覽器的補丁(實現):
這是一個很好的功能解決方案:
基本上,
Object.keys
將鍵提取到列表中sort
ES5 解決方案:
not_sorted = {b: false, a: true};
sorted = Object.keys(not_sorted)
.sort()
.reduce(function (acc, key) {
acc[key] = not_sorted[key];
return acc;
}, {});
console.log(sorted) //{a: true, b: false}
ES6 解決方案:
not_sorted = {b: false, a: true}
sorted = Object.keys(not_sorted)
.sort()
.reduce((acc, key) => ({
...acc, [key]: not_sorted[key]
}), {})
console.log(sorted) //{a: true, b: false}
就在這里。 不在 ECMAScript 標准內,但跨瀏覽器和 Node.js 支持,並且顯然穩定。 請參閱https://stackoverflow.com/a/23202095/645715 。
編輯:這將返回一個對象,其中鍵是有序的。 您可以使用Object.keys(...)
從對象中獲取有序鍵。
為什么要擔心對象鍵順序? 這種差異在某些應用程序中可能很重要,例如使用xml2js解析 XML,它將 XML 表示為嵌套對象,並使用 XML 標記作為哈希鍵。
有幾個注意事項:
Object.keys(obj)
報告for (var key in obj) {...}
報告的順序在 Safari、Firefox 中可能不同該函數返回一個按字母順序插入排序鍵的對象:
function orderKeys(obj, expected) {
var keys = Object.keys(obj).sort(function keyOrder(k1, k2) {
if (k1 < k2) return -1;
else if (k1 > k2) return +1;
else return 0;
});
var i, after = {};
for (i = 0; i < keys.length; i++) {
after[keys[i]] = obj[keys[i]];
delete obj[keys[i]];
}
for (i = 0; i < keys.length; i++) {
obj[keys[i]] = after[keys[i]];
}
return obj;
}
這是一個快速測試:
var example = {
"3": "charlie",
"p:style": "c",
"berries": "e",
"p:nvSpPr": "a",
"p:txBody": "d",
"apples": "e",
"5": "eagle",
"p:spPr": "b"
}
var obj = orderKeys(example);
這返回
{ '3': 'charlie',
'5': 'eagle',
apples: 'e',
berries: 'e',
'p:nvSpPr': 'a',
'p:spPr': 'b',
'p:style': 'c',
'p:txBody': 'd' }
然后,您可以按以下方式獲取有序鍵:
Object.keys(obj)
哪個返回
["3", "5", "apples", "berries", "p:nvSpPr", "p:spPr", "p:style", "p:txBody"]
您也可以通過這種方式對其進行排序。
const data = {
States: ['NSW', 'VIC'],
Countries: ['GBR', 'AUS'],
Capitals: ['SYD', 'MEL']
}
const sortedObject = Object.fromEntries(Object.entries(data).sort())
我無法詳細解釋為什么它有效,但顯然它完美無缺:) 如果您不相信我,請嘗試自己:D
請注意,您的瀏覽器或 Node.js 版本應支持Object.fromEntries
有關瀏覽器兼容性,請查看本頁底部
對於 Node,它將適用於 12 及更高版本。 對於 v1 中的 Deno。
我會將此作為評論添加到@prototype的帖子中,但我的代表還不夠高。
如果有人需要orderKeys
編寫的符合eslint-config-airbnb
:
/**
* Returns and modifies the input object so that its keys are returned in sorted
* order when `Object.keys(obj)` is invoked
*
* @param {object} obj The object to have its keys sorted
*
* @returns {object} The inputted object with its keys in sorted order
*/
const orderKeys = (obj) => {
// Complying with `no-param-reassign`, and JavaScript seems to assign by reference here
const newObj = obj;
// Default `.sort()` chained method seems to work for me
const keys = Object.keys(newObj).sort();
const after = {};
// Add keys to `after` in sorted order of `obj`'s keys
keys.forEach((key) => {
after[key] = newObj[key];
delete newObj[key];
});
// Add keys back to `obj` in sorted order
keys.forEach((key) => {
newObj[key] = after[key];
});
return newObj;
};
使用@prototype的測試:
const example = {
3: 'charlie',
'p:style': 'c',
berries: 'e',
'p:nvSpPr': 'a',
'p:txBody': 'd',
apples: 'e',
5: 'eagle',
p:spPr: 'b'
}
const obj = orderKeys(example);
console.log(obj);
console.log(Object.keys(obj));
輸出以下內容:
Babel Compiler v6.4.4
Copyright (c) 2014-2015 Sebastian McKenzie
{ 3: 'charlie',
5: 'eagle',
apples: 'e',
berries: 'e',
'p:nvSpPr': 'a',
'p:spPr': 'b',
'p:style': 'c',
'p:txBody': 'd' }
[ '3',
'5',
'apples',
'berries',
'p:nvSpPr',
'p:spPr',
'p:style',
'p:txBody' ]
不管它值多少錢,我都需要在我的 React 應用程序中使用它,以便我可以對基於state
對象的下拉列表的選項進行排序,該狀態對象是在我的 API 響應后分配的。
最初我做了
return (
// ...
<Select
options={Object.keys(obj).sort()}
// ...
/>
// ...
);
但是意識到.sort()
方法會在每次重新渲染時被調用,因此需要@prototype的orderKeys
實現。
這是使用lodash對對象的鍵進行排序的單線器
_.chain(obj).toPairs().sortBy(0).fromPairs().value()
使用您的示例數據:
var data = {
'States': ['NSW', 'VIC'],
'Countries': ['GBR', 'AUS'],
'Capitals': ['SYD', 'MEL']
}
data = _.chain(data)
.toPairs() // turn the object into an array of [key, value] pairs
.sortBy(0) // sort these pairs by index [0] which is [key]
.fromPairs() // convert array of pairs back into an object {key: value}
.value() // return value
/*
{
Capitals: [ 'SYD', 'MEL' ],
Countries: [ 'GBR', 'AUS' ],
States: [ 'NSW', 'VIC' ]
}
*/
如果您有一個更復雜的對象,其中一些屬性也是對象,這是一個很好的解決方案。
const sortObject = (obj: any) => {
const sorted = Object.keys(obj)
.sort()
.reduce((accumulator, key) => {
if (typeof obj[key] === "object") {
// recurse nested properties that are also objects
if (obj[key] == null) {
accumulator[key] = null;
} else if (isArray(obj[key])) {
accumulator[key] = obj[key].map((item: any) => {
if (typeof item === "object") {
return sortObject(item);
} else {
return item;
}
});
} else {
accumulator[key] = sortObject(obj[key]);
}
} else {
accumulator[key] = obj[key];
}
return accumulator;
}, {});
return sorted;
};
如果轉換為數組不適合您的模板並且您知道對象的鍵,您也可以執行以下操作:
在您的控制器中,以正確的順序定義一個帶有鍵的數組:
this.displayOrder = [
'firstKey',
'secondKey',
'thirdKey'
];
在您的模板中重復 displayOrder 的鍵,然后使用 ng-init 引用回您的對象。
<div ng-repeat="key in ctrl.displayOrder" ng-init="entry = ctrl.object[key]">
{{ entry.detail }}
</div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.