使用 Javascript 和 lodash 的多标准排序对象键
Multicriteria sorting object keys using Javascript and loadash
我正在尝试使用多个条件 Javascript 和 Lodash 按键对对象进行排序。我不必使用 Lodash,但认为那样会更容易。我对此时任何可行的方法持开放态度。如有任何帮助,我们将不胜感激!!提前谢谢你。
这是我正在使用的示例对象:
var object = {
"148295945589000200_149099156236000910_filter": "some value",
"148295945589000200_149099156236000910_filtertype": "some_value",
"148295945589000200_filter": "asdf",
"149098531921500909_source": "js.content_ids",
"149098531921500909_filtertype": "some_value",
"148295944269000199_settovar": "",
"148295945589000200_149098530604100908_source": "js.content_type",
"148295945589000200_filtertype": "defined",
"148295945589000200_source": "js.content_type",
"148295944269000199_settotext": "adsf",
"148295945589000200_149098530604100908_filter": "some value",
"149099546962400202_149099548423700203_filtertype": "some_value",
"149099546962400202_149099548423700203_filter": "some value",
"148295945589000200_149098530604100908_filtertype": "some_value",
"148295944269000199_setoption": "text",
"148295944269000199_set": "js.content_name",
"149099546962400202_source": "js.acme_id",
"149099546962400202_149099548423700203_source": "js.acme_page",
"149099546962400202_filter": "",
"149098531921500909_filter": "some value",
"149099546962400202_filtertype": "defined",
"148295945589000200_149099156236000910_source": "js.content_name"
}
这就是我想要做的:
根据每个键中的前 18 个数字对对象进行排序。如果只有一个数字块,请先列出它,然后按顺序列出带有第二个数字块的键。然后,按键的剩余字母部分排序。
预期输出:
var object = {
"148295944269000199_set": "js.content_name",
"148295944269000199_setoption": "text",
"148295944269000199_settotext": "adsf",
"148295944269000199_settovar": "",
"148295945589000200_filter": "asdf",
"148295945589000200_filtertype": "defined",
"148295945589000200_source": "js.content_type",
"148295945589000200_149098530604100908_filter": "some value",
"148295945589000200_149098530604100908_filtertype": "some_value",
"148295945589000200_149098530604100908_source": "js.content_type",
"148295945589000200_149099156236000910_filter": "some text",
"148295945589000200_149099156236000910_filtertype": "some_value",
"148295945589000200_149099156236000910_source": "js.content_name"
"149098531921500909_filter": "some value",
"149098531921500909_filtertype": "contains_ignore_case",
"149098531921500909_source": "js.content_ids",
"149099546962400202_filter": "",
"149099546962400202_filtertype": "defined",
"149099546962400202_source": "js.acme_page",
"149099546962400202_149099548423700203_filter": "some value",
"149099546962400202_149099548423700203_filtertype": "some_value",
"149099546962400202_149099548423700203_source": "js.acme_id"
}
以下是我尝试过的一些方法:
(1) 尝试添加到数组并排序
var array = Object.keys(object).sort(function(a, b) {
return a.localeCompare(b);
})
var newObject = {};
array.forEach(function(key) {
newObject[key] = object[key];
});
JSON.stringify(object, null, 2);
(2) 尝试删除下划线进行排序
var newObject = {};
Object.keys(object).forEach(function(key) {
newKey = key.replace(/_/g, "");
newObject[newKey] = object[key];
});
var array = Object.keys(newObject).sort(function(a, b) {
return a.localeCompare(b);
})
var newestObject = {};
array.forEach(function(key) {
newestObject[key] = newObject[key];
});
JSON.stringify(object, null, 2);
(3) 尝试使用 lodash(用“_”调用)转换为多维数组并使用多标准排序 - 我想我可能最接近这个。这需要 lodash 才能工作 -https://raw.githubusercontent.com/lodash/lodash/4.17.4/dist/lodash.core.js
var sortable = _.toPairs(object);
var array = sortable.sort(function(a, b) {
// check if b[0].substring(19,37) is a number first?
if (a[0].substring(0, 18) === b[0].substring(0, 18)) {
var x = a[1].substring(0, 18),
y = b[1].substring(0, 18);
return x < y ? -1 : x > y ? 1 : 0;
}
return a[0].substring(0, 18) - b[0].substring(0, 18);
});
var output = _.fromPairs(array);
JSON.stringify(output, null, 2);
我们可以通过以下方式解决这个问题:
- 正在使用
lodash#toPairs
. 将对象转换为键值对集合
- 使用
lodash#sortBy
按键对集合进行排序:
- 用
'_'
分隔符拆分密钥字符串并得到它 length
.
- 用拆分的
length
替换键字符串中第一个出现的 '_'
字符。
- 使用
lodash#fromPairs
将排序后的集合转换为对象。
var result = _(object)
.toPairs()
.sortBy(function(pair) {
return pair[0].replace(/_/, pair[0].split('_').length);
})
.fromPairs()
.value();
var object = {
"148295945589000200_149099156236000910_filter": "some value",
"148295945589000200_149099156236000910_filtertype": "some_value",
"148295945589000200_filter": "asdf",
"149098531921500909_source": "js.content_ids",
"149098531921500909_filtertype": "some_value",
"148295944269000199_settovar": "",
"148295945589000200_149098530604100908_source": "js.content_type",
"148295945589000200_filtertype": "defined",
"148295945589000200_source": "js.content_type",
"148295944269000199_settotext": "adsf",
"148295945589000200_149098530604100908_filter": "some value",
"149099546962400202_149099548423700203_filtertype": "some_value",
"149099546962400202_149099548423700203_filter": "some value",
"148295945589000200_149098530604100908_filtertype": "some_value",
"148295944269000199_setoption": "text",
"148295944269000199_set": "js.content_name",
"149099546962400202_source": "js.acme_id",
"149099546962400202_149099548423700203_source": "js.acme_page",
"149099546962400202_filter": "",
"149098531921500909_filter": "some value",
"149099546962400202_filtertype": "defined",
"148295945589000200_149099156236000910_source": "js.content_name"
};
var result = _(object)
.toPairs()
.sortBy(function(pair) {
return pair[0].replace(/_/, pair[0].split('_').length);
})
.fromPairs()
.value();
console.log(result);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
或者,您可以不使用 lodash 来解决这个问题:
function getKey(key) {
return key.replace(/_/, key.split('_').length);
}
var result = Object.keys(object)
.sort(function(k1, k2) {
return getKey(k1).localeCompare(getKey(k2));
})
.reduce(function(acc, key) {
acc[key] = object[key];
return acc;
}, {});
var object = {
"148295945589000200_149099156236000910_filter": "some value",
"148295945589000200_149099156236000910_filtertype": "some_value",
"148295945589000200_filter": "asdf",
"149098531921500909_source": "js.content_ids",
"149098531921500909_filtertype": "some_value",
"148295944269000199_settovar": "",
"148295945589000200_149098530604100908_source": "js.content_type",
"148295945589000200_filtertype": "defined",
"148295945589000200_source": "js.content_type",
"148295944269000199_settotext": "adsf",
"148295945589000200_149098530604100908_filter": "some value",
"149099546962400202_149099548423700203_filtertype": "some_value",
"149099546962400202_149099548423700203_filter": "some value",
"148295945589000200_149098530604100908_filtertype": "some_value",
"148295944269000199_setoption": "text",
"148295944269000199_set": "js.content_name",
"149099546962400202_source": "js.acme_id",
"149099546962400202_149099548423700203_source": "js.acme_page",
"149099546962400202_filter": "",
"149098531921500909_filter": "some value",
"149099546962400202_filtertype": "defined",
"148295945589000200_149099156236000910_source": "js.content_name"
};
function getKey(key) {
return key.replace(/_/, key.split('_').length);
}
var result = Object.keys(object)
.sort(function(k1, k2) {
return getKey(k1).localeCompare(getKey(k2));
})
.reduce(function(acc, key) {
acc[key] = object[key];
return acc;
}, {});
console.log(result);
body > div { min-height: 100%; top: 0; }
我正在尝试使用多个条件 Javascript 和 Lodash 按键对对象进行排序。我不必使用 Lodash,但认为那样会更容易。我对此时任何可行的方法持开放态度。如有任何帮助,我们将不胜感激!!提前谢谢你。
这是我正在使用的示例对象:
var object = {
"148295945589000200_149099156236000910_filter": "some value",
"148295945589000200_149099156236000910_filtertype": "some_value",
"148295945589000200_filter": "asdf",
"149098531921500909_source": "js.content_ids",
"149098531921500909_filtertype": "some_value",
"148295944269000199_settovar": "",
"148295945589000200_149098530604100908_source": "js.content_type",
"148295945589000200_filtertype": "defined",
"148295945589000200_source": "js.content_type",
"148295944269000199_settotext": "adsf",
"148295945589000200_149098530604100908_filter": "some value",
"149099546962400202_149099548423700203_filtertype": "some_value",
"149099546962400202_149099548423700203_filter": "some value",
"148295945589000200_149098530604100908_filtertype": "some_value",
"148295944269000199_setoption": "text",
"148295944269000199_set": "js.content_name",
"149099546962400202_source": "js.acme_id",
"149099546962400202_149099548423700203_source": "js.acme_page",
"149099546962400202_filter": "",
"149098531921500909_filter": "some value",
"149099546962400202_filtertype": "defined",
"148295945589000200_149099156236000910_source": "js.content_name"
}
这就是我想要做的:
根据每个键中的前 18 个数字对对象进行排序。如果只有一个数字块,请先列出它,然后按顺序列出带有第二个数字块的键。然后,按键的剩余字母部分排序。
预期输出:
var object = {
"148295944269000199_set": "js.content_name",
"148295944269000199_setoption": "text",
"148295944269000199_settotext": "adsf",
"148295944269000199_settovar": "",
"148295945589000200_filter": "asdf",
"148295945589000200_filtertype": "defined",
"148295945589000200_source": "js.content_type",
"148295945589000200_149098530604100908_filter": "some value",
"148295945589000200_149098530604100908_filtertype": "some_value",
"148295945589000200_149098530604100908_source": "js.content_type",
"148295945589000200_149099156236000910_filter": "some text",
"148295945589000200_149099156236000910_filtertype": "some_value",
"148295945589000200_149099156236000910_source": "js.content_name"
"149098531921500909_filter": "some value",
"149098531921500909_filtertype": "contains_ignore_case",
"149098531921500909_source": "js.content_ids",
"149099546962400202_filter": "",
"149099546962400202_filtertype": "defined",
"149099546962400202_source": "js.acme_page",
"149099546962400202_149099548423700203_filter": "some value",
"149099546962400202_149099548423700203_filtertype": "some_value",
"149099546962400202_149099548423700203_source": "js.acme_id"
}
以下是我尝试过的一些方法:
(1) 尝试添加到数组并排序
var array = Object.keys(object).sort(function(a, b) {
return a.localeCompare(b);
})
var newObject = {};
array.forEach(function(key) {
newObject[key] = object[key];
});
JSON.stringify(object, null, 2);
(2) 尝试删除下划线进行排序
var newObject = {};
Object.keys(object).forEach(function(key) {
newKey = key.replace(/_/g, "");
newObject[newKey] = object[key];
});
var array = Object.keys(newObject).sort(function(a, b) {
return a.localeCompare(b);
})
var newestObject = {};
array.forEach(function(key) {
newestObject[key] = newObject[key];
});
JSON.stringify(object, null, 2);
(3) 尝试使用 lodash(用“_”调用)转换为多维数组并使用多标准排序 - 我想我可能最接近这个。这需要 lodash 才能工作 -https://raw.githubusercontent.com/lodash/lodash/4.17.4/dist/lodash.core.js
var sortable = _.toPairs(object);
var array = sortable.sort(function(a, b) {
// check if b[0].substring(19,37) is a number first?
if (a[0].substring(0, 18) === b[0].substring(0, 18)) {
var x = a[1].substring(0, 18),
y = b[1].substring(0, 18);
return x < y ? -1 : x > y ? 1 : 0;
}
return a[0].substring(0, 18) - b[0].substring(0, 18);
});
var output = _.fromPairs(array);
JSON.stringify(output, null, 2);
我们可以通过以下方式解决这个问题:
- 正在使用
lodash#toPairs
. 将对象转换为键值对集合
- 使用
lodash#sortBy
按键对集合进行排序:- 用
'_'
分隔符拆分密钥字符串并得到它length
. - 用拆分的
length
替换键字符串中第一个出现的'_'
字符。
- 用
- 使用
lodash#fromPairs
将排序后的集合转换为对象。
var result = _(object)
.toPairs()
.sortBy(function(pair) {
return pair[0].replace(/_/, pair[0].split('_').length);
})
.fromPairs()
.value();
var object = {
"148295945589000200_149099156236000910_filter": "some value",
"148295945589000200_149099156236000910_filtertype": "some_value",
"148295945589000200_filter": "asdf",
"149098531921500909_source": "js.content_ids",
"149098531921500909_filtertype": "some_value",
"148295944269000199_settovar": "",
"148295945589000200_149098530604100908_source": "js.content_type",
"148295945589000200_filtertype": "defined",
"148295945589000200_source": "js.content_type",
"148295944269000199_settotext": "adsf",
"148295945589000200_149098530604100908_filter": "some value",
"149099546962400202_149099548423700203_filtertype": "some_value",
"149099546962400202_149099548423700203_filter": "some value",
"148295945589000200_149098530604100908_filtertype": "some_value",
"148295944269000199_setoption": "text",
"148295944269000199_set": "js.content_name",
"149099546962400202_source": "js.acme_id",
"149099546962400202_149099548423700203_source": "js.acme_page",
"149099546962400202_filter": "",
"149098531921500909_filter": "some value",
"149099546962400202_filtertype": "defined",
"148295945589000200_149099156236000910_source": "js.content_name"
};
var result = _(object)
.toPairs()
.sortBy(function(pair) {
return pair[0].replace(/_/, pair[0].split('_').length);
})
.fromPairs()
.value();
console.log(result);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
或者,您可以不使用 lodash 来解决这个问题:
function getKey(key) {
return key.replace(/_/, key.split('_').length);
}
var result = Object.keys(object)
.sort(function(k1, k2) {
return getKey(k1).localeCompare(getKey(k2));
})
.reduce(function(acc, key) {
acc[key] = object[key];
return acc;
}, {});
var object = {
"148295945589000200_149099156236000910_filter": "some value",
"148295945589000200_149099156236000910_filtertype": "some_value",
"148295945589000200_filter": "asdf",
"149098531921500909_source": "js.content_ids",
"149098531921500909_filtertype": "some_value",
"148295944269000199_settovar": "",
"148295945589000200_149098530604100908_source": "js.content_type",
"148295945589000200_filtertype": "defined",
"148295945589000200_source": "js.content_type",
"148295944269000199_settotext": "adsf",
"148295945589000200_149098530604100908_filter": "some value",
"149099546962400202_149099548423700203_filtertype": "some_value",
"149099546962400202_149099548423700203_filter": "some value",
"148295945589000200_149098530604100908_filtertype": "some_value",
"148295944269000199_setoption": "text",
"148295944269000199_set": "js.content_name",
"149099546962400202_source": "js.acme_id",
"149099546962400202_149099548423700203_source": "js.acme_page",
"149099546962400202_filter": "",
"149098531921500909_filter": "some value",
"149099546962400202_filtertype": "defined",
"148295945589000200_149099156236000910_source": "js.content_name"
};
function getKey(key) {
return key.replace(/_/, key.split('_').length);
}
var result = Object.keys(object)
.sort(function(k1, k2) {
return getKey(k1).localeCompare(getKey(k2));
})
.reduce(function(acc, key) {
acc[key] = object[key];
return acc;
}, {});
console.log(result);
body > div { min-height: 100%; top: 0; }