将数据包装为对象形式

时间:2018-12-11 13:46:29

标签: javascript ecmascript-6

我有一个像这样的数据集:

[ { city: 'a', value: 1, sector: 'Hospital' },
  { city: 'b', value: 1, sector: 'Hardware' },
  { city: 'c', value: 1, sector: 'Hardware' },
  { city: 'd', value: 1, sector: 'Networking' },
  { city: 'e', value: 1, sector: 'Hospital' },
  { city: 'f', value: 1, sector: 'Education' },
  { city: 'g', value: 1, sector: 'Transport' },
  { city: 'h', value: 1, sector: 'Food' },
  { city: 'i', value: 1, sector: 'Networking' },
  { city: 'j', value: 0.7, sector: 'Software' },
  { city: 'k', value: 0.7, sector: 'Education' },
  { city: 'l', value: 0.7, sector: 'Food' },
  { city: 'm', value: 0.7, sector: 'Hospital' },
  { city: 'n', value: 0.2, sector: 'Networking' },
  { city: 'o', value: 0.2, sector: 'Networking' },
  { city: 'p', value: 0.2, sector: 'Industrial' },
  { city: 'q', value: 0.2, sector: 'Transport' },
  { city: 'r', value: 0.2, sector: 'Software' } ]

现在我想将对象数组转换为带有Array的对象,具有相同重复扇区的城市应归入特定组。

所需的输出如下:

[
 {
  sector: "Hospital",
  place: ["a", "e", "m"]
 },
 {
  sector: "Hardware",
  place: ["b", "c"]
 },
 {
  sector: "Networking",
  place: ["d", "i", "n", "o"]
 },
 {
  sector: "Education",
  place: ["f", "k"]
 },
 {
  sector: "Transport",
  place: ["g", "q"]
 },
 {
  sector: "Food",
  place: ["h", "l"]
 },
 {
  sector: "Software",
  place: ["j", "r"]
 },
 {
  sector: "Industrial",
  place: ["q"]
 },
]

有没有人建议我如何完成这类任务。 任何帮助或建议都非常感谢。

我有一个线索,这些事情将通过reduce和map函数来完成,但是这将是一个挑战。

我试图获得像这样的扇区重复计数,但是没有达到我想要的输出:

let x = data.reduce((m, c) => {
  if (c.sector in m) m[c.sector].count += 1;
   else m[c.sector] = { sector: c.sector, count: 1 };
   return m;
}, {});
console.log(x)

3 个答案:

答案 0 :(得分:5)

您可以首先提取uniq中的所有array扇区。

之后,map进入每个扇区,数据中的filter对应。

var data = [{ city: 'a', value: 1, sector: 'Hospital' },
  { city: 'b', value: 1, sector: 'Hardware' },
  { city: 'c', value: 1, sector: 'Hardware' },
  { city: 'd', value: 1, sector: 'Networking' },
  { city: 'e', value: 1, sector: 'Hospital' },
  { city: 'f', value: 1, sector: 'Education' },
  { city: 'g', value: 1, sector: 'Transport' },
  { city: 'h', value: 1, sector: 'Food' },
  { city: 'i', value: 1, sector: 'Networking' },
  { city: 'j', value: 0.7, sector: 'Software' },
  { city: 'k', value: 0.7, sector: 'Education' },
  { city: 'l', value: 0.7, sector: 'Food' },
  { city: 'm', value: 0.7, sector: 'Hospital' },
  { city: 'n', value: 0.2, sector: 'Networking' },
  { city: 'o', value: 0.2, sector: 'Networking' },
  { city: 'p', value: 0.2, sector: 'Industrial' },
  { city: 'q', value: 0.2, sector: 'Transport' },
  { city: 'r', value: 0.2, sector: 'Software' } ];
  
  
  var sectors = [];
  
  data.map(d => {
    if(sectors.indexOf(d.sector) === -1){
       sectors.push(d.sector);
    }
  })
  
  sectors = sectors.map(sector => {
     return {
        sector,
        places:data.filter(d => d.sector === sector).map(d => d.city)
     }
  });
  
  console.log(sectors)

答案 1 :(得分:1)

reducefindIndex的使用略有不同。无需通过这种方式创建单独的键数组。

const data = [{"city":"a","value":1,"sector":"Hospital"},{"city":"b","value":1,"sector":"Hardware"},{"city":"c","value":1,"sector":"Hardware"},{"city":"d","value":1,"sector":"Networking"},{"city":"e","value":1,"sector":"Hospital"},{"city":"f","value":1,"sector":"Education"},{"city":"g","value":1,"sector":"Transport"},{"city":"h","value":1,"sector":"Food"},{"city":"i","value":1,"sector":"Networking"},{"city":"j","value":0.7,"sector":"Software"},{"city":"k","value":0.7,"sector":"Education"},{"city":"l","value":0.7,"sector":"Food"},{"city":"m","value":0.7,"sector":"Hospital"},{"city":"n","value":0.2,"sector":"Networking"},{"city":"o","value":0.2,"sector":"Networking"},{"city":"p","value":0.2,"sector":"Industrial"},{"city":"q","value":0.2,"sector":"Transport"},{"city":"r","value":0.2,"sector":"Software"}];
  
const out = data.reduce((acc, c) => {

  // Grab the sector and city
  const { sector, city } = c;

  // Find an object in the array that matches the sector
  const found = acc.findIndex(el => el.sector === sector);

  // If it exists...
  if (found > -1) {

    // ...push a new city to the place array
    acc[found].place.push(city);
  } else {

    // ...otherwise push a new object to the array
    // with the starter city
    acc.push({ sector, place: [city] });
  }

  return acc;

}, []);

console.log(out);

答案 2 :(得分:0)

您可以创建一个函数,该函数将在数组上使用reduce进行迭代并将唯一的扇区存储在数组中,然后使用mapfilter返回具有所需值的数组。

function normalize (input){
  const sectors = input.reduce(function(result, value){
    if(result.indexOf(value.sector) === -1){
      result.push(value.sector);
    }  
    return result;
  }, []);

  return sectors.map(function(sector){
    return {
      sector,
      places: input.filter(function(entry){
        return entry.sector === sector;
      }).map(function(entry){
        return entry.city;
      })
    }
  });
}