2021-11-09 23:55:42 +08:00
|
|
|
|
import { isArray, isPlainObject } from 'lodash';
|
|
|
|
|
|
2025-05-12 22:06:02 +08:00
|
|
|
|
/**
|
|
|
|
|
* @returns A deep clone of the object, but with any null value removed.
|
|
|
|
|
* @param value - The object to be cloned and cleaned.
|
|
|
|
|
* @param convertInfinity - If true, -Infinity or Infinity is converted to 0.
|
|
|
|
|
* This is because Infinity is not a valid JSON value, and sometimes we want to convert it to 0 instead of default null.
|
|
|
|
|
*/
|
|
|
|
|
export function sortedDeepCloneWithoutNulls<T>(value: T, convertInfinity?: boolean): T {
|
2021-11-09 23:55:42 +08:00
|
|
|
|
if (isArray(value)) {
|
2025-05-12 22:06:02 +08:00
|
|
|
|
return value.map((item) => sortedDeepCloneWithoutNulls(item, convertInfinity)) as unknown as T;
|
2021-11-09 23:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
if (isPlainObject(value)) {
|
2025-02-13 22:20:17 +08:00
|
|
|
|
return Object.keys(value as { [key: string]: any })
|
2021-11-09 23:55:42 +08:00
|
|
|
|
.sort()
|
|
|
|
|
.reduce((acc: any, key) => {
|
|
|
|
|
const v = (value as any)[key];
|
2025-05-12 22:06:02 +08:00
|
|
|
|
// Remove null values
|
|
|
|
|
if (v != null) {
|
|
|
|
|
acc[key] = sortedDeepCloneWithoutNulls(v, convertInfinity);
|
2021-11-09 23:55:42 +08:00
|
|
|
|
}
|
2025-05-12 22:06:02 +08:00
|
|
|
|
|
|
|
|
|
if (convertInfinity && (v === Infinity || v === -Infinity)) {
|
|
|
|
|
acc[key] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-09 23:55:42 +08:00
|
|
|
|
return acc;
|
|
|
|
|
}, {});
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
}
|