javascript 按对象的多个字段将数组拆分为子数组

fykwrbwg  于 2022-12-10  发布在  Java
关注(0)|答案(3)|浏览(132)

我用很多对象组成了这样的数组:

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

我想按字段将此数组拆分为子数组:'起始货币ID','终止货币ID':

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

我试过使用lodash group by和native方法,但是我还不知道如何正确地使用。希望你能帮助我。
我最后一次尝试:

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

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

其中data是我的数组。接下来,我想从对象中删除键,从而得到我的新数组

scyqe7ek

scyqe7ek1#

groupBy方法应该返回一个一致的“key”,以便将相似的对象分组,但当前的方法不能做到这一点,因为_.find()没有用于任何数据(只传递了一个参数)。
下面我使用reduce创建了一个Map(类似于一个对象),map中的每个键都是一个唯一的键,它将fromCurrencyIdtoCurrencyId属性组合在一起,并将值存储为具有相同货币id组合的对象数组。
请参见以下工作示例(以及代码注解以了解更多详细信息):

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);

使用lodash的一种方法是先使用_.groupBy(),然后使用_.at()获取fromCurrencyIdtoCurrencyId处的值(_.at()就像您_.pick(),但它返回的是一个值数组而不是一个对象)。(通过一个隐式的.toString()调用)当它被用作_.groupBy()返回的对象的键时,你可以用_.values()来获取分组值:
第一次

cuxqih21

cuxqih212#

我用some检查结果中是否已经存在子数组,如果没有,我用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);
ru9i0ody

ru9i0ody3#

lodash也许可以用更少的步骤来完成,但我想在不使用外部库的情况下演示答案(目前)
请参阅内嵌注解以了解原因:

// 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
// e.g. "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)
  • 编辑:* 我已经修改了我的答案并纠正了我的错误

相关问题