我喜欢下面的json
[
{name:'aa',age:'1Y',address:'Alaska'},
{name:'cc',age:'4Years',address:'California'},
{name:'mm',address:'Texas'}
]
每当我按名称排序并解决它的工作时,如果我尝试按年龄排序,它会抛出运行时错误,因为它在最后一个条目中缺失。
这是我的尝试
let obj=[
{name:'aa',age:'2y',address:'Alaska'},
{name:'cc',age:'4y',address:'California'},
{name:'bb',address:'Texas'}
]
let field='age'; //work for name and address;
let mode='string';
if(mode!='number'){
console.log (obj.sort((a, b) => a[field].toString().localeCompare(b[field].toString())));
}
else{
console.log(obj.sort((a, b) => a[field] -b[field]))
}
当键不存在时忽略条目的最佳方法是什么,在排序之前是否需要使用单独的循环来检查键。缺少密钥的条目将位于底部。
Ps:年龄从未超过业务逻辑10年,它们可以采用任何格式,如1,1Y,因此被视为字符串
答案 0 :(得分:4)
确保您拥有该对象的值,或返回一个空字符串。
最短的代码路径是
(a[field] || "")
如果您指出如果a
没有该属性,则会将其视为空字符串。
它不会涵盖a
null
,所以如果发生这种情况,你必须更仔细地检查它
let obj = [{
name: 'aa',
age: '25',
address: 'Alaska'
},
{
name: 'cc',
age: '25',
address: 'California'
},
{
name: 'bb',
address: 'Texas'
}
]
let field = 'age'; //work for name and address
console.log(obj.sort((a, b) => (a[field] || "").toString().localeCompare((b[field] || "").toString())));
另一种方法是简单地比较这些值(请注意,如果a
或b
为空,则可能存在问题)
let obj = [{
name: 'aa',
age: 25,
address: 'Alaska'
},
{
name: 'cc',
age: 3,
address: 'California'
},
{
name: 'bb',
address: 'Texas'
}
]
function sortAndPrint( obj, field ) {
console.log(`Sorting by ${field}`);
console.log(obj.sort((a, b) => a[field] > b[field] ) );
}
sortAndPrint(obj, 'name');
sortAndPrint(obj, 'address');
sortAndPrint(obj, 'age');
答案 1 :(得分:1)
缺少键的输入将位于底部
要求当前值来决定将要比较的内容或底部的内容。
let obj=[{name:'aa',age:'2y',address:'Alaska'},{name:'cc',age:'4y',address:'California'},{name:'bb',address:'Texas'}],
field = 'age';
console.log(obj.sort((a, b) => a[field] ? b[field] ? a[field].toString().localeCompare(b[field].toString()) : -1 : 1));

.as-console-wrapper { max-height: 100% !important; top: 0; }

如果要比较此字符串10years
或此字符串5y
中的数字,依此类推,请使用正则表达式比较数字。
let obj=[{name:'aa',age:'24y',address:'Alaska'},{name:'cc',age:'4years',address:'California'},{name:'bb',address:'Texas'}],
field = 'age';
console.log(obj.sort((a, b) => {
let evaluate = () => {
let aval = a[field].replace(/[^\d]/g, '').trim();
let bval = b[field].replace(/[^\d]/g, '').trim();
return aval !== '' && bval !== '' ? Number(aval) - Number(bval) : a[field].toString().localeCompare(b[field].toString());
};
return a[field] ? b[field] ? evaluate() : -1 : 1
}));

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)
let obj=[
{name:'aa',age:'25',address:'Alaska'},
{name:'cc',age:'25',address:'California'},
{name:'bb',address:'Texas'}
]
let field='age'; //work for name and address
const sortFunc = (a, b) => a[field].toString().localeCompare(b[field].toString())
// If you can discard entries without the field
console.log(obj.filter(e => field in e).sort(sortFunc))
// If you cannot
console.log(obj.filter(e => field in e).sort(sortFunc).concat(obj.filter(e => !(field in e))))
答案 3 :(得分:0)
这是因为在您尝试使用属性toString访问它时,在最后一个元素上没有属性年龄。(使用年龄键为null)
答案 4 :(得分:0)
以防您正在寻找过度杀伤解决方案:)
let obj=[
{name: 'aa', age: 25, address: 'Alaska'},
{name: 'cc', age: 24, address: 'California'},
{name: 'mm', address: 'Texas'}
];
let field = 'age';
console.log (obj.sort((a, b) => {
a = a[field];
b = b[field];
let defaultValue = '';
if (typeof a === 'number' || typeof b === 'number') {
defaultValue = 0;
}
a = a || defaultValue;
b = b || defaultValue;
if (typeof a === 'number') {
return a - b;
}
else {
return a.localeCompare(b);
}
}));
这会自动处理字符串或数字,为每个字符串或数字正确排序。如果您希望no-age条目排序更高而不是低于其他所有条目,只需将数字defaultValue
设置为大数字即可。