使用Javascript按属性值拆分对象数组

时间:2016-01-16 09:31:11

标签: javascript arrays object group-by

我有一个包含对象的数组。我需要创建多个数组,其中的对象按其中一个属性值分组。澄清这里是我的阵列:

sudo apt-get update 
sudo apt-get install gitlab-ce

我希望有一个阵列,其中所有人名为Scott,其中一个人名为Jesse,依此类推。任何建议都会有所帮助。

2 个答案:

答案 0 :(得分:2)

要做到这一点,你可以循环遍历数组条目(在any of several ways中,让我们在这里使用forEach)并创建一个对象或Map用你所遇到的名字键入,值是这些名称的条目数组。

以下是使用对象的示例:

// Create an object with no prototype, so it doesn't have "toString"
// or "valueOf", although those would be unlikely names for people to have
var nameArrays = Object.create(null);

// Loop the people array
people.forEach(function(person) {
    // Get the name array for this person's name, if any
    var nameArray = nameArrays[person.firstName];
    if (!nameArray) {
        // There wasn't one, create it
        nameArray = nameArrays[person.firstName] = [];
    }
    // Add this entry
    nameArray.push(person);
});

直播示例:

function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
}
var people = [
  new Person("Scott", "Guthrie", 38),
  new Person("Scott", "Johns", 36),
  new Person("Scott", "Hanselman", 39),
  new Person("Jesse", "Liberty", 57),
  new Person("Jon", "Skeet", 38)
];

// Create an object with no prototype, so it doesn't have "toString"
// or "valueOf", although those would be unlikely names for people to have
var nameArrays = Object.create(null);

// Loop the people array
people.forEach(function(person) {
  // Get the name array for this person's name, if any
  var nameArray = nameArrays[person.firstName];
  if (!nameArray) {
    // There wasn't one, create it
    nameArray = nameArrays[person.firstName] = [];
  }
  // Add this entry
  nameArray.push(person);
});

// Show results
Object.keys(nameArrays).sort().forEach(function(firstName) {
  snippet.log(
    "People named " + firstName +
    ": " +
    nameArrays[firstName].map(function(person) {
      return person.firstName + " " + person.lastName;
    }).join(", ")
  );
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

ES2015在语言中添加了Map,因此在ES2015环境中,我们可能会使用Map而不是nameArrays的对象:

// Creating the map:
let nameArrays = new Map();

// Getting an array:
nameArray = nameArrays.get(person.firstName);

// Adding an array:
nameArrays.set(person.firstName, []);

// Looping through the map:
for (let [firstName, nameArray] of nameArrays) {
    // Use `firstName` and `nameArray` here
}

答案 1 :(得分:1)

这是一个更通用的解决方案。 getGroupedBy(persons, key)返回一个数组数组,按键分组人员。

function Person(firstName, lastName, age) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
}

var people = [
    new Person("Scott", "Guthrie", 38),
    new Person("Scott", "Johns", 36),
    new Person("Scott", "Hanselman", 39),
    new Person("Jesse", "Liberty", 57),
    new Person("Jon", "Skeet", 38)
];

function getGroupedBy(persons, key) {
    var groups = {}, result = [];
    persons.forEach(function (a) {
        if (!(a[key] in groups)) {
            groups[a[key]] = [];
            result.push(groups[a[key]]);
        }
        groups[a[key]].push(a);
    });
    return result;
}

document.write('<pre>' + JSON.stringify(getGroupedBy(people, 'firstName'), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(getGroupedBy(people, 'lastName'), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(getGroupedBy(people, 'age'), 0, 4) + '</pre>');