返回数组中每组具有最高属性值的对象

时间:2018-12-24 15:22:41

标签: javascript arrays

我有一个包含多个类似于以下对象的数组:

{person: {name: "Steve", id: 1}, role: 1}
{person: {name: "Phil", id: 2}, role: 1}
{person: {name: "Steve", id: 1}, role: 3}
{person: {name: "Phil", id: 2}, role: 6}

我的意图是返回一个相同类型的数组,但我想每个“人”仅返回一个具有最高作用的对象。

我了解以下内容将给我一个具有最高作用的对象。

array.reduce((prev, cur) => prev.role > cur.role ? prev : cur);

如何将每个唯一的人及其相应的最高角色作为新数组返回?

像这样:

{person: {name: "Steve", id: 1}, role: 3}
{person: {name: "Phil", id: 2}, role: 6}

3 个答案:

答案 0 :(得分:4)

您需要收集这些物体,如果已经有一个具有相同id的物体,请检查role并取出较大的物体。

var data = [{ person: { name: "Steve", id: 1 }, role: 1 }, { person: { name: "Phil", id: 2 }, role: 1 }, { person: { name: "Steve", id: 1 }, role: 3 }, { person: { name: "Phil", id: 2 }, role: 6 }],
    grouped = data.reduce((r, o) => {
        var index = r.findIndex(({ person: { id } }) => id === o.person.id);
        if (index === -1) {
            r.push(o);
            return r;
        }
        if (r[index].role < o.role) {
            r[index] = o;
        }
        return r;    
    }, []);

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

将项目按person.idArray.reduce()分组,但是对于每个id,仅存储角色最高的对象。使用Object.values()转换回数组:

const data = [{ person: { name: "Steve", id: 1 }, role: 1 }, { person: { name: "Phil", id: 2 }, role: 1 }, { person: { name: "Steve", id: 1 }, role: 3 }, { person: { name: "Phil", id: 2 }, role: 6 }];

const result = Object.values(data.reduce((r, o) => {
  const id = o.person.id;
  
  if(!r[id] || r[id].role < o.role) r[id] = o;
  
  return r;
}, []));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:1)

您可以使用Array.prototype.reduce并构建如下的对象文字。使用person.name属性值作为对象键,然后在发现更高的值时更新角色值:

var people = [{
  person: {
    name: "Steve",
    id: 1
  },
  role: 1
}, {
  person: {
    name: "Phil",
    id: 2
  },
  role: 1
}, {
  person: {
    name: "Steve",
    id: 1
  },
  role: 3
}, {
  person: {
    name: "Phil",
    id: 2
  },
  role: 6
}];

var highRoleByPerson = people.reduce((accum, el) => {
  if (accum[el.person.name]) {
    if (el.role > accum[el.person.name].role) {
      accum[el.person.name].role = el.role;
    }
  } else {
    accum[el.person.name] = {
      person: {
        name: el.person.name,
        id: el.person.id
      },
      role: 0
    };
  }
  return accum;
}, {});

console.log(highRoleByPerson);