简体   繁体   English

通过 object 的多字段将数组拆分为子数组

[英]Split the array into sub-arrays by multi-fields of the object

I have such array with a lot of objects:我有很多对象的数组:

[
  {
    startAt: "2016-01-01 11:35:00",
    fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a",
    toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e"
  },
  {
    startAt: "2016-01-01 11:40:00",
    fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a",
    toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e"
  },
  {
    startAt: "2016-01-01 12:00:00",
    fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e",
    toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302"
  },
  {
    startAt: "2016-01-01 12:40:00",
    fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e",
    toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302"
  },
  {
    startAt: "2016-01-01 11:40:00",
    fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a",
    toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302"
  },
  ...
]

I would like to split this array into sub-arrays by fields: 'fromCurrencyId', 'toCurrencyId':我想按字段将此数组拆分为子数组:“fromCurrencyId”、“toCurrencyId”:

[
  [
    {
      startAt: "2016-01-01 11:35:00",
      fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a",
      toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e"
    },
    {
      startAt: "2016-01-01 11:40:00",
      fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a",
      toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e"
    }
  ],
  [
    {
      startAt: "2016-01-01 12:00:00",
      fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e",
      toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302"
    },
    {
      startAt: "2016-01-01 12:40:00",
      fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e",
      toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302"
    }
  ],
  [
    {
      startAt: "2016-01-01 11:40:00",
      fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a",
      toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302"
    }
  ]
]

I've tried using lodash group by and native methods, but I don't understand how to do it correctly yet.我试过使用 lodash group by 和 native 方法,但我还不知道如何正确地使用它。 I hope for your help.我希望得到你的帮助。

My last attempt:我最后的尝试:

const props = ['fromCurrencyId', 'toCurrencyId']

const a = _.groupBy(data, function(note){
  return _.find(_.pick(note, props));
});

where data is my array.数据是我的数组。 And next, I wanted to delete the keys from the object and thereby get my new array接下来,我想从 object 中删除键,从而得到我的新数组

lodash may be able to do it in fewer steps but I wanted to demonstrate an answer without using external libraries (for now) lodash可以用更少的步骤完成,但我想在不使用外部库的情况下展示一个答案(目前)

See the inline comments for reasoning:推理见内嵌注释:

 // key name we're targetting const targetIds = ["fromCurrencyId", "toCurrencyId"]; // your data const data = [{ startAt: "2016-01-01 11:35:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e" }, { startAt: "2016-01-01 11:40:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e" }, { startAt: "2016-01-01 12:00:00", fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, { startAt: "2016-01-01 12:40:00", fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, { startAt: "2016-01-01 11:40:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, ] // A set of the unique values for the given key name // `.join` is used to create a unique string made up of the values of teh targetIds const uniq = Array.from(new Set(data.map(item => targetIds.map(target => item[target]).join(",")))); // console.log(uniq) // Map over the Array, and then for each item // eg "5491dfe0-7d61-407d-b642-7fd3ec905302" // Filter out your original data for each item to get an Array of Arrays // `.split` is then used in combination with `every` to find the _values_ of the targetIds const subData = uniq.map(combinedValue => data.filter(d => combinedValue.split(",").every((value, index) => d[targetIds[index]] === value))); console.log(subData)

Edit: I have modified my answer and rectified my mistake编辑:我已经修改了我的答案并纠正了我的错误

here is my attend.这是我的出席。 i use some to check if the sub-arrays already exist in the result.我用some来检查结果中是否已经存在子数组。 if not, i use filter to find the matching fromCurrencyId and toCurrencyId and then create a sub-arrays and push it to the result.如果没有,我使用filter找到匹配的fromCurrencyIdtoCurrencyId ,然后创建一个子数组并将其推送到结果。

 const data = [ { startAt: "2016-01-01 11:35:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e" }, { startAt: "2016-01-01 11:40:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e" }, { startAt: "2016-01-01 12:00:00", fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, { startAt: "2016-01-01 12:40:00", fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, { startAt: "2016-01-01 11:40:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, ] const result = data.reduce((p, c, _, arr) => { if (.p.some(p => p.some(p => p.fromCurrencyId === c.fromCurrencyId && p.toCurrencyId === c.toCurrencyId))) { p.push(arr.filter(a => a.fromCurrencyId === c.fromCurrencyId && a.toCurrencyId === c;toCurrencyId)), } return p }. []) console;log(result);

Your groupBy method should return a consistent "key" that you want to group similar objects on.您的 groupBy 方法应该返回一个一致的“键”,您希望在该键上对相似对象进行分组。 Your current approach doesn't do that, as your _.find() is not being used on any data (you're only passing one argument to it).您当前的方法不会这样做,因为您的_.find()未用于任何数据(您只向其传递一个参数)。

Instead, you can do this without lodash.相反,您可以在没有 lodash 的情况下执行此操作。 Below I've used reduce to create a Map (similar to an object).下面我使用reduce创建了一个Map (类似于一个对象)。 Each key in the map is a unique key that combines the fromCurrencyId with the toCurrencyId properties, and stores a value as an array of objects with the same currency id combination. map 中的每个键都是一个唯一键,它结合了fromCurrencyIdtoCurrencyId属性,并将值存储为具有相同货币 ID 组合的对象数组。

See working example below (and code comments for more details):请参阅下面的工作示例(以及更多详细信息的代码注释):

 const arr = [ { startAt: "2016-01-01 11:35:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e" }, { startAt: "2016-01-01 11:40:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e" }, { startAt: "2016-01-01 12:00:00", fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, { startAt: "2016-01-01 12:40:00", fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, { startAt: "2016-01-01 11:40:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" } ]; const res = Array.from(arr.reduce((map, obj) => { const key = `${obj.fromCurrencyId}-${obj.toCurrencyId}`; // create the key const curr = map.get(key) || []; // get the grouped objects if the key already exists, otherwise creattee an empty array return map.set(key, curr.concat(obj)); // add the current object to the array, at our currency id key }, new Map).values()); console.log(res);

One approach using lodash is to use _.groupBy() and then use _.at() to grab the values at fromCurrencyId and toCurrencyId ( _.at() is like your _.pick() , but it returns an array of values instead of an object).使用 lodash 的一种方法是使用_.groupBy()然后使用_.at()获取fromCurrencyIdtoCurrencyId的值( _.at()就像你的_.pick() ,但它返回一个值数组而不是一个对象)。 This array of values is automatically converted into a string (via an implicit .toString() call) when it's used as a key for the object _.groupBy() returns.当该值数组用作 object _.groupBy()返回的键时,它会自动转换为字符串(通过隐式.toString()调用)。 You can then take the _.values() of the object to get just the grouped values:然后,您可以使用 object 的_.values()来获取分组值:

 const arr = [ { startAt: "2016-01-01 11:35:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e" }, { startAt: "2016-01-01 11:40:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e" }, { startAt: "2016-01-01 12:00:00", fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, { startAt: "2016-01-01 12:40:00", fromCurrencyId: "c5a0c46c-c5b5-49a5-9a16-4a829269583e", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" }, { startAt: "2016-01-01 11:40:00", fromCurrencyId: "a49cd579-18ea-44cb-8117-86428b64a27a", toCurrencyId: "5491dfe0-7d61-407d-b642-7fd3ec905302" } ]; const props = ['fromCurrencyId', 'toCurrencyId']; const a = _.values(_.groupBy(arr, note => _.at(note, props), "-")); console.log(a);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

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

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