简体   繁体   English

Javascript尝试根据内部对象数组值对对象数组进行排序

[英]Javascript trying to sort array of objects based on inner object array values

I'm not sure if there is an easy solution to this problem, but I want to sort an array of objects, that have a nested array of objects, based on this array of objects y value and the parent x key.我不确定这个问题是否有一个简单的解决方案,但我想根据这个对象数组 y 值和父 x 键对具有嵌套对象数组的对象数组进行排序。 The difficult part is that both of the arrays get combined together to represent some data.困难的部分是两个数组组合在一起来表示一些数据。

Here is the data structure这是数据结构

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}
    ]
  }
]

At this stage, there is only the two parent objects, so I need to compare each object and reorder them, the end result would look like在这个阶段,只有两个父对象,所以我需要比较每个对象并重新排序它们,最终结果看起来像

[
  {
    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
    ]
  }
]

I've tried a couple of ideas but can't seem to find a solution to my problem if you've seen a nice solution elsewhere please feel free to link it.我已经尝试了几个想法,但似乎无法找到解决我的问题的方法,如果您在其他地方看到了不错的解决方案,请随时链接它。

Here is something I tried这是我尝试过的东西

series.forEach(obj => {
  obj.data.sort((a, b) => {
    return b.y - a.y;
  });
});

But it just ends up moving the highest values in each array to the top, not the one which should match the other array.但它最终只会将每个数组中的最高值移动到顶部,而不是应该与另一个数组匹配的那个。 It's hard to give context but I'm using Apexcharts which uses the data to make a graph like this:很难给出上下文,但我正在使用 Apexcharts,它使用数据来制作这样的图表:

    | testData | testData2
---------------------------
abc  ------ GraphBar ------ 
def  ------ AnotherBar ----
ghi  ------ thirdBar ------
jkl  ------ fourthBar -----
---------------------------

So I need to figure out how to sort based on the bar's cumulative values, based on both the two objects data array y values.所以我需要弄清楚如何基于条形的累积值进行排序,基于两个对象数据数组 y 值。

This is what it looks like presorting这就是预排序的样子

这是数据在排序前的样子

And after, as you can see its modifying the data之后,如您所见,它正在修改数据

在我整理之后

Assuming that we name the variable series as in假设我们将变量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 }
        ]
    }
]

(note that I've made the x properties have string values instead of bare identifiers like abc ; I assume that's what you want) (请注意,我已经使x属性具有string值而不是像abc这样的裸标识符;我假设这就是您想要的)

We can possibly tackle your sorting task like this.我们可以像这样处理您的排序任务。 First, let's get an object whose keys are the x values and whose values are the sums of the y values:首先,让我们得到一个对象,它的键是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 }

Note that I'm using the comma operator inside the reduce where the first part does the mutation and the last part hands back the object to be mutated.请注意,我在reduce中使用逗号运算符,其中第一部分进行变异,最后一部分交回要变异的对象。 It's not necessarily any better than using a for loop, other than being terse.除了简洁之外,它不一定比使用for循环更好。

Now we can sort the data in series by using sums :现在我们可以使用sumsdata进行series排序:

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
      }
    ]
  }
]
*/

Looks reasonable to me.对我来说看起来很合理。 Okay, hope that helps;好的,希望有帮助; good luck!祝你好运!

Link to code 代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM