描述
我的解决方案是这个。我决定先将对象展平:
function flattenObject(value: any): any {
let toReturn: any = {};
for (const i in value) {
if (!value.hasOwnProperty(i)) {
continue;
}
if (typeof value[i] == 'object') {
const flatObject = flattenObject(value[i]);
for (const x in flatObject) {
if (!flatObject.hasOwnProperty(x)) continue;
toReturn[i + '.' + x] = flatObject[x];
}
} else {
toReturn[i] = value[i];
}
}
return toReturn;
}
然后我将从对象中提取值:
function nestedFieldValue(
nestedJoinedFieldByDot: string,
obj: any,
): any {
return flattenObject(obj)[nestedJoinedFieldByDot];
}
最后我只需要这样做:
export function fieldSorter(fields: string[]) {
return function (a: any, b: any) {
return fields
.map(function (fieldKey) {
let dir = 1;
if (fieldKey[0] === '-') {
dir = -1;
fieldKey = fieldKey.substring(1);
}
const aValue = nestedFlattenObjectFieldValue(
fieldKey,
a,
);
const bValue = nestedFlattenObjectFieldValue(
fieldKey,
b,
);
if (
typeof aValue === 'number' ||
typeof bValue === 'number'
) {
if (aValue ?? 0 > bValue ?? 0) {
return dir;
}
if (aValue ?? 0 < bValue ?? 0) {
return -dir;
}
} else {
if (aValue ?? 0 > bValue ?? 0) {
return dir;
}
if (aValue ?? 0 < bValue ?? 0) {
return -dir;
}
}
return 0;
})
.reduce(function firstNonZeroValue(p, n) {
return p ? p : n;
}, 0);
};
}
最后我们需要做这个:
const unsorted = [
{
city: {
priority: 1,
name: 'Tokyo',
airport: { name: 'Haneda Airport' }
}
}
]
const result = unsorted.sort(
fieldSorter(['city.priority', 'city.airport.name', 'city.name']),
);
我认为这种方式更加清晰和简洁。它易读且更加实用。我合并了来自stackoverflow的多个答案以达到这个解决方案:sweat_smile:
{nestedobj:{property:'g'}}, {nestedobj:{property:'F'}}, {nestedobj:{property:'abcd'}}, {nestedobj:{property:'abba'}}
- Alan Wells