如何有效地将项目归为成对的存储桶(如果有的话)

时间:2019-08-12 22:41:56

标签: javascript functional-programming lodash

我正在创建一个自动的排名匹配系统,其中两个候选人可以选择彼此排名,然后系统根据两个候选人的排名找到最佳匹配对。

更具体地说,“海报”创建了一个帖子,而“申请人”则应用了,该应用程序创建了两个排名条目,以允许双方分别排名。

我首先从数据库中获取这些排名,以产生数据结构数组:

rankings ==> [ {postID, rankerID, rankeeID, ranking}, ...]

然后我通过postID(与Lodash的groupBy)对这些排名进行存储:

_.groupBy(rankings, rank => rank.postID);

这将通过postID产生分类排名,例如:

{
  postID_1: [
    { postID: 'postID_1', rankerID: 'applicantA', rankeeID: 'posterA', ranking: 1 },
    { postID: 'postID_1', rankerID: 'posterA', rankeeID: 'applicantA', ranking: 4 }
  ],
  postID_2: [
    { postID: 'postID_2', rankerID: 'posterB', rankeeID: 'applicantA', ranking: 3 },
    { postID: 'postID_2', rankerID: 'applicantA', rankeeID: 'posterB', ranking: 5 },
    { postID: 'postID_2', rankerID: 'applicantB', rankeeID: 'posterB', ranking: 1 }
  ],
  ...
}

请注意,并非总是有完整的配对显示海报==>申请人和申请人==>海报的排名。

最终,我想根据特定标准及其排名来确定谁是最佳的招贴申请人匹配候选人,所以我需要确定如何将上述结构转换为成对的桶,以达到预期的结果:

{
  postID_1: [
    [
      { rankerID: 'applicantA', rankeeID: 'posterA', ... },
      { rankerID: 'posterA', rankeeID: 'applicantA', ... }
    ]
  ],
  postID_2: [
    [
      { rankerID: 'applicantA', rankeeID: 'posterB', ... },
      { rankerID: 'posterB', rankeeID: 'applicantA', ... }
    ],
    [
      { rankerID: 'applicantB', rankeeID: 'posterB', ... }
    ]
  ],
  ...
}

在用功能性编程对(可能是)现有的配对进行存储时,我在制定数据转换时遇到麻烦。

1 个答案:

答案 0 :(得分:0)

您在这里!我们使用Array.reduce并检查“一对的另一半”是否已经存在,如果存在,请完成。否则,我们将添加新的一对。

const data = {  postID_1: [    {      postID: "postID_1",      rankerID: "applicantA",      rankeeID: "posterA",      ranking: 1    },    {      postID: "postID_1",      rankerID: "posterA",      rankeeID: "applicantA",      ranking: 4    }  ],  postID_2: [    {      postID: "postID_2",      rankerID: "posterB",      rankeeID: "applicantA",      ranking: 3    },    {      postID: "postID_2",      rankerID: "applicantA",      rankeeID: "posterB",      ranking: 5    },    {      postID: "postID_2",      rankerID: "applicantB",      rankeeID: "posterB",      ranking: 1    }  ]};

const result = Object.entries(data).reduce(
  (accResult, [key, postData]) => ({
    ...accResult,
    [key]: postData.reduce((acc, val) => {
      const secondHalf = acc.find(
        ([{ rankerID, rankeeID }]) =>
          rankerID === val.rankeeID && rankeeID === val.rankerID
      );
      if (secondHalf) {
        secondHalf.push(val);
        return acc;
      } else {
        return acc.concat([[val]]);
      }
    }, [])
  }),
  {}
);

console.log(result);