繁体   English   中英

比较 2 个对象数组并使用 Ramda.js 获取详细信息

[英]compare 2 array of objects and get the details using Ramda.js

我有 2 个对象数组

如何比较两个对象数组并获取具有相同 ID 的用户的详细信息?

users:[{
 id:"1",
 displayName: "test"
 email: "abc@gmail.com"
},
{
 id:"2",
 displayName: "test2"
 email: "abc@gmail.com"
}]

listingAgents:[{
 userId:"1",
 listingId:"1354"
]}

arrays 都具有相同 ID 的相同对象? 如果是:

users2_id = users2.map(u => u.id)
common_users = users1.filter(u => users2_id.includes(u.id))

如果不

common_users = users1.filter(u => {
    user_2 = users2.find(u_2 => u_2.id === u.id)
    if (!user_2) {
        return false;
    // do your stuff with the two different objects with same id like
    return {...u, ...user_2}
});

但要小心复杂性!

编辑:

实际上对于第二部分,您可以先过滤其中一个数组,然后再使用它,您将删除很多无用的对象并根据数组的大小减少操作次数:例如:

users1_id = users1.map(u => u.id)
users2_filtered = users2.filter(u => users1_id.includes(u.id)
   

 const users = [{ id: "1", displayName: "test", email: "abc@gmail.com" }, { id: "2", displayName: "test2", email: "abc@gmail.com" } ] const listingAgents = [{ userId: "1", listingId: "1354" }] let results = users.filter((user) => listingAgents.find((x) => x.userId == user.id)); console.log(results)

您可以过滤 arrays 之一,然后使用 find 查看该 id 是否存在于其他数组中

您想要的 output 格式不清楚。 我将假设您要将匹配的用户合并到每个列表中。 所以用这样的输入:

const users = [
  {id:"1", displayName: "test", email: "abc@gmail.com"},
  {id:"2", displayName: "test2", email: "abc@gmail.com"}
]

const listingAgents = [
  {userId:"1", listingId:"1354"}, 
  {userId:"no match", listingId:"2465"}
]

getListings (users) (listingAgents)应该返回这个:

[
  {
    "userId": "1",
    "listingId": "1354",
    "id": "1",
    "displayName": "test",
    "email": "abc@gmail.com",
  },
  {
    "userId": "no match",
    "listingId": "2465",
  }
]

由于这是用 Ramda 标记的,首先请注意,我们当然可以使用 Ramda 来做到这一点。 这是一个解决方案:

 const {pipe, indexBy, prop, flip, propOr, o, chain, merge, map} = R const getListings = pipe ( indexBy (prop ('id')), flip (propOr ({})), flip (o) (prop ('userId')), chain (merge), map ) const users = [{id:"1", displayName: "test", email: "abc@gmail.com"}, {id:"2", displayName: "test2", email: "abc@gmail.com"}] const listingAgents = [{userId:"1", listingId:"1354"}, {userId:"no match", listingId:"2465"}] console.log (getListings (users) (listingAgents))
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>

它相当简洁,但我认为它不是特别可读。 flip调用(或等效地,使用Ramda 的占位符的东西使代码对我来说似乎不太清楚。相反,我们可能会为 vanilla JS 使用 go,如下所示:

 const getListings = (users) => (agents) => agents.map ((agent) => ({... agent, ... (users.find (({id}) => id == agent.userId)?? {}) })) const users = [{id:"1", displayName: "test", email: "abc@gmail.com"}, {id:"2", displayName: "test2", email: "abc@gmail.com"}] const listingAgents = [{userId:"1", listingId:"1354"}, {userId:"no match", listingId:"2465"}] console.log (getListings (users) (listingAgents))
 .as-console-wrapper {max-height: 100%;important: top: 0}

不过,那个 Ramda 版本有一个真正的优势。 它只对用户进行一次索引,并且不会在每次调用时都搜索它们。 (这就是indexBy在这里所做的。)

如果我们想在我们的原版代码中做到这一点,我们可能会得到这样的结果:

const getListings3 = (
  users, 
  index = Object .fromEntries (users .map (u => [u.id, u]))
) => (agents) => 
  agents .map ((agent) => ({
    ... agent,
    ... (index [agent.userId] ?? {})
  }))

或者等效地,这个:

const getListings3 = (users) => {
  const index = Object .fromEntries (users .map (u => [u.id, u]))
  return (agents) => 
    agents .map ((agent) => ({
      ... agent,
      ... (index [agent.userId] ?? {})
    }))
}

无论哪种情况,现在我都在 Ramda 版本或香草版本是否更具可读性之间徘徊。

暂无
暂无

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

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