潇湘沐
您可以为此使用递归函数。很难根据问题中的信息给出一个确切的例子,但例如:function process(obj) { // Loop through the values of the own properties of the object for (const value of Object.values(obj)) { // Is this the termination condition? if (Array.isArray(value)) { // <== A guess at the condition, adjust as needed // We've reached the bottom value.sort((x, y) => x.date.localeCompare(y.date)); // <== Note correction, you can't just return the result of `>` } else { // Not the termination, recurse process(value); } }}使用猜测数据的实时示例:function process(obj) { // Loop through the values of the own properties of the object for (const value of Object.values(obj)) { // Is this the termination condition? if (Array.isArray(value)) { // <== A guess at the condition, adjust as needed // We've reached the bottom value.sort((x, y) => x.date.localeCompare(y.date)); // <== Note correction, you can't just return the result of `>` } else { // Not the termination, recurse process(value); } }}const objRes = { group1: { type1: { name1: { tenor1: [ {date: '2019-12-23', value: 35}, {date: '2019-12-25', value: 32}, {date: '2019-12-24', value: 30}, ] }, name2 :[] }, type2: {} }, group2: {}};process(objRes);console.log(JSON.stringify(objRes, null, 4));.as-console-wrapper { max-height: 100% !important;}一些注意事项:您可以通过使用来避免for-in/hasOwnProperty组合Object.values。您可以使用 遍历这些值for-of。必须有一些终止条件告诉函数何时到达“底部”。在那个例子中,我使用了Array.isArray因为你在最后一级排序。Array.prototype.sort 直接修改数组,不需要使用它的返回值。您传递给的函数sort必须返回负数、0 或正数,而不是布尔值(更多信息请点击此处)。由于您的date值在yyyy-MM-dd形式上似乎是字符串,因此您可以使用localeCompare它(因为在这种格式中,字典比较也是日期比较)。
叮当猫咪
这个替代 TJ Crowder 的答案采用了那里提到的几个决策点,并使它们显式函数调用。const process = (test, transform, data) => typeof data == "object" ? ( Array .isArray (data) ? (xs) => xs .map (([_, x]) => x) : Object .fromEntries ) ( Object .entries (data) .map (([k, v]) => [k, test (k, v) ? transform (v) : process (test, transform, v)] )) : data 它接受两个函数以及您的数据对象。第一个是测试您是否遇到了要按摩的嵌套值。所以我们可以想象像(k, v) => k .startsWith ('tenor')或 之类的东西(k, v) => Array .isArray (v)。第二个函数接受该条目处的值并返回一个更新的值,可能是(v) => v . sort((a, b) => a .date .localeCompare (b .date))。(注意:您的排序调用是有问题的。不要使用.sort ((a, b) => a < b),它返回一个布尔值,然后被强制转换为 a0或 a 1,而适当的比较器应该返回-1when a < b。如果您可以与 进行比较<,那么这应该始终有效(a, b) => a < b ? -1 : a > b ? 1 : 0。我不”不知道是否有比使用 .sort((a,b) => a>b) 对数组进行排序更完整的问题。为什么?。)您可以在此代码段中看到它的运行情况:const process = (test, transform, data) => typeof data == "object" ? ( Array .isArray (data) ? (xs) => xs .map (([_, x]) => x) : Object .fromEntries ) ( Object .entries (data) .map (([k, v]) => [k, test (k, v) ? transform (v) : process (test, transform, v)] )) : data const dateSort = (xs) => xs .slice (0) .sort ((a, b) => a .date .localeCompare (b .date))const objRes = { group1: { type1: { name1: { tenor1: [ {date: '2019-12-23', value: 35}, {date: '2019-12-25', value: 32}, {date: '2019-12-24', value: 30}, ] }, name2: [] }, type2: {} }, group2: { type3: [ {date: '2020-01-03', value: 42}, {date: '2019-01-01', value: 43}, {date: '2019-01-02', value: 44}, ] }};// This one only sorts the first group of datesconsole .log ( process ( (k, v) => k .startsWith ('tenor'), dateSort, objRes ))// This one sorts both groupsconsole .log ( process ( (k, v) => Array .isArray (v), dateSort, objRes ))代码有点密集。最外层条件仅在数据是对象时才应用我们的处理,如果不是则完整返回,如果是则执行以下处理:我们首先使用Object.entries将我们的对象转换为名称-值对,然后通过测试每一对来映射该对象,看看我们是否遇到了应该转换的东西,并返回转换后的值或对值进行递归的结果。也许最棘手的一点是: ( Array .isArray (data) ? (xs) => xs .map (([_, x]) => x) : Object .fromEntries )在这里,我们只选择一个函数应用到转换后的对上,将其重新变成一个整体。如果它是一个数组,我们跳过键并返回一个值数组。如果不是,我们就用它们Object.fromEntries来创建一个对象。如果Object.entries是不是在你的环境中使用,很容易垫片。