Javascript 尝试根据内部对象数组值对对象数组进行排序
Javascript trying to sort array of objects based on inner object array values
我不确定这个问题是否有简单的解决方案,但我想根据这个对象数组的 y 值和父对象 x 对具有嵌套对象数组的对象数组进行排序钥匙。困难的部分是两个数组组合在一起以表示一些数据。
这是数据结构
series: [
{
name: 'testData',
data: [
{x: abc, y: 488},
{x: def, y: 65},
{x: ghi, y: 380},
{x: jkl, y: 190}
]
},
{
name: 'testData2',
data: [
{x: abc, y: 241},
{x: def, y: 232},
{x: ghi, y: 72},
{x: jkl, y: 724}
]
}
]
在这个阶段,只有两个父对象,所以我需要比较每个对象并重新排序,最终结果会像
[
{
name: 'testData',
data: [
{x: jkl, y: 190}, // total for key jkl y combined values is 914
{x: abc, y: 488}, // total for key abc y combined values is 729
{x: ghi, y: 380}, // total for key ghi y combined values is 452
{x: def, y: 65}, // total for key def y combined values is 297
]
},
{
name: 'testData2',
data: [
{x: jkl, y: 724}, // total for key jkl y combined values is 914
{x: abc, y: 241}, // total for key abc y combined values is 729
{x: ghi, y: 72}, // total for key ghi y combined values is 452
{x: def, y: 232} // total for key def y combined values is 297
]
}
]
我已经尝试了几个想法,但似乎无法找到解决我的问题的方法,如果您在其他地方看到了一个不错的解决方案,请随时 link 它。
这是我试过的东西
series.forEach(obj => {
obj.data.sort((a, b) => {
return b.y - a.y;
});
});
但它只是将每个数组中的最高值移动到顶部,而不是应该与另一个数组匹配的值。很难给出上下文,但我使用的是 Apexcharts,它使用数据制作如下图表:
| testData | testData2
---------------------------
abc ------ GraphBar ------
def ------ AnotherBar ----
ghi ------ thirdBar ------
jkl ------ fourthBar -----
---------------------------
所以我需要弄清楚如何根据柱形的累积值,基于两个对象数据数组 y 值进行排序。
这就是预排序的样子
之后,如您所见,它正在修改数据
假设我们将变量series
命名为
const series = [
{
name: 'testData',
data: [
{ x: 'abc', y: 488 },
{ x: 'def', y: 65 },
{ x: 'ghi', y: 380 },
{ x: 'jkl', y: 190 }
]
},
{
name: 'testData2',
data: [
{ x: 'abc', y: 241 },
{ x: 'def', y: 232 },
{ x: 'ghi', y: 72 },
{ x: 'jkl', y: 724 }
]
}
]
(请注意,我已经使 x
属性具有 string
值,而不是像 abc
这样的裸标识符;我假设这就是您想要的)
我们可能会像这样处理您的排序任务。首先,让我们得到一个对象,它的键是 x
个值,它的值是 y
个值的总和:
const sums = series.reduce(
(s, r) => (r.data.forEach(xy => s[xy.x] = (s[xy.x] || 0) + xy.y), s),
{} as Record<string, number>
);
console.log(sums); // { abc: 729, def: 297, ghi: 452, jkl: 914 }
请注意,我在 reduce
中使用 comma operator,其中第一部分进行变异,最后一部分交回要变异的对象。除了简洁之外,它不一定比使用 for
循环更好。
现在我们可以使用 sums
:
对 series
中的 data
进行排序
series.forEach(v => v.data.sort((a, b) => sums[b.x] - sums[a.x]));
console.log(JSON.stringify(series,null,2));
/*
[
{
"name": "testData",
"data": [
{
"x": "jkl",
"y": 190
},
{
"x": "abc",
"y": 488
},
{
"x": "ghi",
"y": 380
},
{
"x": "def",
"y": 65
}
]
},
{
"name": "testData2",
"data": [
{
"x": "jkl",
"y": 724
},
{
"x": "abc",
"y": 241
},
{
"x": "ghi",
"y": 72
},
{
"x": "def",
"y": 232
}
]
}
]
*/
我觉得很合理。好的,希望有所帮助;祝你好运!
我不确定这个问题是否有简单的解决方案,但我想根据这个对象数组的 y 值和父对象 x 对具有嵌套对象数组的对象数组进行排序钥匙。困难的部分是两个数组组合在一起以表示一些数据。
这是数据结构
series: [
{
name: 'testData',
data: [
{x: abc, y: 488},
{x: def, y: 65},
{x: ghi, y: 380},
{x: jkl, y: 190}
]
},
{
name: 'testData2',
data: [
{x: abc, y: 241},
{x: def, y: 232},
{x: ghi, y: 72},
{x: jkl, y: 724}
]
}
]
在这个阶段,只有两个父对象,所以我需要比较每个对象并重新排序,最终结果会像
[
{
name: 'testData',
data: [
{x: jkl, y: 190}, // total for key jkl y combined values is 914
{x: abc, y: 488}, // total for key abc y combined values is 729
{x: ghi, y: 380}, // total for key ghi y combined values is 452
{x: def, y: 65}, // total for key def y combined values is 297
]
},
{
name: 'testData2',
data: [
{x: jkl, y: 724}, // total for key jkl y combined values is 914
{x: abc, y: 241}, // total for key abc y combined values is 729
{x: ghi, y: 72}, // total for key ghi y combined values is 452
{x: def, y: 232} // total for key def y combined values is 297
]
}
]
我已经尝试了几个想法,但似乎无法找到解决我的问题的方法,如果您在其他地方看到了一个不错的解决方案,请随时 link 它。
这是我试过的东西
series.forEach(obj => {
obj.data.sort((a, b) => {
return b.y - a.y;
});
});
但它只是将每个数组中的最高值移动到顶部,而不是应该与另一个数组匹配的值。很难给出上下文,但我使用的是 Apexcharts,它使用数据制作如下图表:
| testData | testData2
---------------------------
abc ------ GraphBar ------
def ------ AnotherBar ----
ghi ------ thirdBar ------
jkl ------ fourthBar -----
---------------------------
所以我需要弄清楚如何根据柱形的累积值,基于两个对象数据数组 y 值进行排序。
这就是预排序的样子
之后,如您所见,它正在修改数据
假设我们将变量series
命名为
const series = [
{
name: 'testData',
data: [
{ x: 'abc', y: 488 },
{ x: 'def', y: 65 },
{ x: 'ghi', y: 380 },
{ x: 'jkl', y: 190 }
]
},
{
name: 'testData2',
data: [
{ x: 'abc', y: 241 },
{ x: 'def', y: 232 },
{ x: 'ghi', y: 72 },
{ x: 'jkl', y: 724 }
]
}
]
(请注意,我已经使 x
属性具有 string
值,而不是像 abc
这样的裸标识符;我假设这就是您想要的)
我们可能会像这样处理您的排序任务。首先,让我们得到一个对象,它的键是 x
个值,它的值是 y
个值的总和:
const sums = series.reduce(
(s, r) => (r.data.forEach(xy => s[xy.x] = (s[xy.x] || 0) + xy.y), s),
{} as Record<string, number>
);
console.log(sums); // { abc: 729, def: 297, ghi: 452, jkl: 914 }
请注意,我在 reduce
中使用 comma operator,其中第一部分进行变异,最后一部分交回要变异的对象。除了简洁之外,它不一定比使用 for
循环更好。
现在我们可以使用 sums
:
series
中的 data
进行排序
series.forEach(v => v.data.sort((a, b) => sums[b.x] - sums[a.x]));
console.log(JSON.stringify(series,null,2));
/*
[
{
"name": "testData",
"data": [
{
"x": "jkl",
"y": 190
},
{
"x": "abc",
"y": 488
},
{
"x": "ghi",
"y": 380
},
{
"x": "def",
"y": 65
}
]
},
{
"name": "testData2",
"data": [
{
"x": "jkl",
"y": 724
},
{
"x": "abc",
"y": 241
},
{
"x": "ghi",
"y": 72
},
{
"x": "def",
"y": 232
}
]
}
]
*/
我觉得很合理。好的,希望有所帮助;祝你好运!