简体   繁体   中英

ES6: How do I reduce this array of objects to unique values?

I've been spinning my wheels for way too long trying to work this out and I'm ready to throw my computer out the window. How might I reduce this array:

const array = [
  {'location': "Plovdiv", 'department': "Finance"},
  {'location': "Plovdiv", 'department': "Client & Employee Support"},
  {'location': "Plovdiv", 'department': "Client & Employee Support"},
  {'location': "London", 'department': "Engineering"},
  {'location': "London", 'department': "Engineering"},
  {'location': "Plovdiv", 'department': "Engineering"}
];

to this:

{'location': "Plovdiv", 'department': ["Finance", "Client & Employee Support", "Engineering"]},
{'location': "London", 'department': ["Engineering"]},

My goal is to remove the duplicate arrays in objects with location, and merge them as a single key. Where each key will have the corresponding departments as a list.

edit: I finally managed to figure it out with plain ol' JS, but it's bulky and features a LOT of looping that I could probably get rid of with a more modern approach.

let locArray = [];
  let newGrouping = [];

  // For each location
  for (let i = 0; i < locations.length; i += 1) {
    // Check to see if the current locations is in the new locArray
    if (locArray.indexOf(locations[i].location) === -1) {
      // Get in there!
      locArray.push(locations[i].location);
    }
  }

  // Loop through the new set of unique locations
  for (let i = 0; i < locArray.length; i += 1) {
    let depArray = [];

    // Loop through our original locations array
    for (let j = 0; j < locations.length; j += 1) {
      // Check to see if the current unique location matches the current location
      // AND make sure that it's not already in depArray
      if (locArray[i] === locations[j].location && depArray.indexOf(locations[j].department) === -1) {
        // Get in there!
        depArray.push(locations[j].department);
      }
    }

    // Push our current unique location and its unique departments into a new object
    newGrouping.push({
      'location': locArray[i],
      'departments': depArray
    });
  }

use Set and map

We want to uniquely key on location to do this we use a Set to ensure uniqueness.

  // Notice we use the map function to pull just location. 
  new Set(array.map(({ location }) => location))

But now we need to iterate those unique keys and rebuild our array.
So we load the Set into an Array

 const unique = new Array(...new Set(array.map(({ location }) => location)))

Now we have an array of unique location , from here we can use a map function to build our desired array output.
Notice how as we build our final array of object the department parameter is rehydrated using a filter and map of the original array.

  [Unique Location Array].map(location => ({ 
          location, // ES6 the property name it is inferred
          department: array.filter(({ location: l}) => location === l)
                            .map(({ department }) => department)
          }));

 const array = [ {'location': "Plovdiv", 'department': "Finance"}, {'location': "Plovdiv", 'department': "Client & Employee Support"}, {'location': "Plovdiv", 'department': "Client & Employee Support"}, {'location': "London", 'department': "Engineering"}, {'location': "London", 'department': "Engineering"}, {'location': "Plovdiv", 'department': "Engineering"} ]; const unique = new Array(...new Set(array.map(({ location }) => location))) .map(location => ({ location, department: array.filter(({ location: l}) => location === l) .map(({ department }) => department) })); console.log(unique);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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