【问题标题】:UnderscoreJS - Pull users from an Array who are part of a groupUnderscoreJS - 从数组中拉出属于组的用户
【发布时间】:2018-11-18 17:14:57
【问题描述】:

我有一个组对象:

{groupid1: "metadata",
 groupid2: "metadata"}

还有一组用户:

[
 {
  name: "something",
  groups: ["groupid1", "groupid2"]
  ...},
 {
  name: "something else ",
  groups: ["groupid1"]
  ...},
 {
  name: "something else again",
  groups: ["groupid2"]
  ...},
]

我想遍历组 id 并提取与该组 id 匹配的用户列表,所以我最终记录了两个用户列表,每个组一个:

for (group in groups) {
 var userArray = _.pluck(users, function(user) { 
  return user.groups.indexOf(group) > -1;
 })
 console.log(userArray);
}

问题是这返回给我一个未定义的数组,而不是一个用户对象的数组。即使只是返回用户名也很好。

感谢您提供的任何帮助! 对于可伸缩性,下划线是解决此问题的首选方法。

【问题讨论】:

  • 嗨 Mike,下划线是解决这个问题的首选方法,而不是纯 JS 方法。
  • 原始 JavaScript 几乎总是比库更“可扩展”。
  • 我正在阅读服务器端节点和下划线,发现在处理更大的数组时(在我的情况下,它将是 ~1000 个用户和 ~20 个组)下划线具有更好的性能。我会再看看这个并与我的同事讨论,谢谢。
  • 仅供参考,Underscore 是用 JavaScript 编写的,所以它不可能有比 JavaScript 更好的性能,因为它是 JavaScript :)。没什么大不了的,你有一个使用图书馆的答案,只是以为我已经完成了。

标签: javascript underscore.js


【解决方案1】:

您的 sn-p 的问题在于您使用的是 _.pluck 而不是 _.select。 下面是 underscore.js 的解决方案:

const groups = {
    groupid1: "metadata",
    groupid2: "metadata"
};

const users = [{
        name: "something",
        groups: ["groupid1", "groupid2"]
    },
    {
        name: "something else ",
        groups: ["groupid1"]
    },
    {
        name: "something else again",
        groups: ["groupid2"]
    },
];

_.each(_.keys(groups), group => {
    const usersArray = _.select(users, user => {
        return user.groups.indexOf(group) > -1;
    });
    console.log(usersArray);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

从这个答案的评论中回答作者的另一个问题:

我想扩展问题以将两者的结果推送到单个数组中,并且不包含重复项

const groups = {
    groupid1: "metadata",
    groupid2: "metadata"
};

const users = [{
        name: "something",
        groups: ["groupid1", "groupid2"]
    },
    {
        name: "something else ",
        groups: ["groupid1"]
    },
    {
        name: "something else again",
        groups: ["groupid2"]
    },
];

let usersArray = [];
_.each(_.keys(groups), group => {
    usersArray = _.union(usersArray, _.select(users, user => {
        return user.groups.indexOf(group) > -1;
    }));
});
console.log(usersArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

【讨论】:

  • 如果我想扩展问题以将两者的结果推送到单个数组中,并且不包含重复项,我应该打开新的堆栈交换问题吗?
  • 嗨,Shubham,如果你能做到这一点,那就太好了!
  • 嘿 Gary,起初我尝试 _.extend 做同样的事情,但发现在阵列上使用它还有许多其他缺点。但后来想出了这个简单的解决方案。请告诉我这是否适合您。
  • 嗨,绝对有效!干杯,感谢帮助。我正在尝试“.concat”和“_.flatten”,但这会导致重复。
【解决方案2】:

正如docs 中所述,_.pluck() 接受两个参数:列表和属性名称 - 您提供的不是属性名称而是一个函数。更重要的是,这不是您使用 _.pluck() 函数的目的(再次查看文档)。

在您的情况下,您甚至根本不需要使用 UnderscoreJS:

// Your groups
const groups = {
  groupid1: "metadata",
  groupid2: "metadata"
};

// Your users
const users = [
 {
  name: "something",
  groups: ["groupid1", "groupid2"],
 },
 {
  name: "something else ",
  groups: ["groupid1"]
 },
 {
  name: "something else again",
  groups: ["groupid2"]
 }
];

// Get ids of the groups and loop through them
const result = Object.keys(groups).forEach(groupId => {
  // Return only users whose groups array contains the groupId
  const usersFound = users.filter(user => user.groups.indexOf(groupId) > -1);
  
  // Log the users found
  console.log(usersFound);
});

【讨论】:

  • 这看起来工作得很好,谢谢。使用 _.pluck() 的原因是因为文档说明它的用途是“提取属性值列表”,在这种情况下,属性值是一个对象 - 虽然我没有正确查看参数。
猜你喜欢
  • 1970-01-01
  • 2013-06-04
  • 2011-11-28
  • 1970-01-01
  • 2011-04-10
  • 1970-01-01
  • 2017-08-08
  • 2013-11-10
  • 2016-10-16
相关资源
最近更新 更多