如何从嵌套数组创建对象数组?

时间:2021-05-17 09:42:21

标签: javascript reactjs

我有以下数组:

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

我需要转换成以下格式:

const a = [{
      Type: 'student',
      Names: [{
          Firstname: 'martha',
          Lastname: 'james'
        },
        {
          Firstname: 'Julie',
          Lastname: 'schrutt'
        }
      ],
    },
    {
      Type: 'Teacher',
      Names: [{
        Firstname: 'meredith',
        Lastname: 'Napier'
      }, ],
    }

我尝试过 lodash 分组、object.entries、数组映射、reduce,但不知道如何去做。

7 个答案:

答案 0 :(得分:4)

您可以在 js 中使用 reduce 轻松实现此结果。

const a = [
  {
    Name: "martha",
    Surname: "james",
    Type: "student",
  },
  {
    Name: "Meredith",
    Surname: "Napier",
    Type: "Teacher",
  },
  {
    Name: "Julie",
    Surname: "Schrutt",
    Type: "student",
  },
];

const result = a.reduce((acc, curr) => {
  const { Name, Surname, Type } = curr;
  const elSearch = acc.find((o) => o.Type === Type);
  if (elSearch) {
    elSearch.Names.push({
      Firstname: Name,
      Lastname: Surname,
    });
  } else {
    acc.push({
      Type,
      Names: [
        {
          Firstname: Name,
          Lastname: Surname,
        },
      ],
    });
  }
  return acc;
}, []);

console.log(result);

如果在 destructuring

期间更改变量名称,则可以缩短上述代码段
const { Name: Firstname, Surname: Lastname, Type } = curr;

并将其用作

elSearch.Names.push({ Firstname, Lastname });

const a = [
  { Name: "martha", Surname: "james", Type: "student"},
  { Name: "Meredith", Surname: "Napier", Type: "Teacher"},
  { Name: "Julie", Surname: "Schrutt", Type: "student"},
];

const result = a.reduce((acc, curr) => {
  const { Name: Firstname, Surname: Lastname, Type } = curr;
  const elSearch = acc.find((o) => o.Type === Type);
  if (elSearch) {
    elSearch.Names.push({ Firstname, Lastname });
  } else {
    acc.push({ Type, Names: [{ Firstname, Lastname }] });
  }

  return acc;
}, []);

console.log(result);

答案 1 :(得分:0)

使用 forEach

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
];

const out = [{Type: 'student', Names: []}, {Type: 'teacher', Names: []}];
a.forEach(a => {
  if (a.Type === 'student')
    return out[0].Names.push({
        Firstname: a.Name,
        Lastname: a.Surname,
    });
  out[1].Names.push({
      Firstname: a.Name,
      Lastname: a.Surname,
  });
});

console.log(out);

答案 2 :(得分:0)

尝试这样的事情:

const output = {};    

for(const person of array) {
    if(!output[person.Type]) output[person.Type] = { Type: person.Type, Names:[] };
    output[person.Type].Names.push({ Firstname: person.Name, Lastname: person.Surname });
}

return Object.values(output);

或者简而言之:

Object.values(array.reduce((pre, curr) => {
    if(!pre[curr.Type]) pre[curr.Type] = { Type: curr.Type, Names:[] };
    pre[curr.Type].Names.push({ Firstname: curr.Name, Lastname: curr.Surname });
    return pre;
} , {}))

答案 3 :(得分:0)

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

const types = a.reduce((acc, next) => {
    if (acc.includes(next.Type)) {
    return acc
  }
  return acc.concat(next.Type)
}, [])

const arrayByTypes = types.map((type) => {
    return {
    Type: type,
    Names: a.filter(item => item.Type === type).map(filtered => ({ Name: filtered.Name, Surname: filtered.Surname }))
    }
})

console.log(arrayByTypes)

答案 4 :(得分:0)

const data = [{
        Name: 'martha',
        Surname: 'james',
        Type: 'student',
    },
    {
        Name: 'Meredith',
        Surname: 'Napier',
        Type: 'Teacher',
    },
    {
        Name: 'Julie',
        Surname: 'Schrutt',
        Type: 'student',
    }
]

function processData(data) {
    finalMap = new Map();
    data.forEach((obj) => {
        let typeName = obj["Type"];
        let firstName = obj["Name"];
        let lastName = obj["Surname"];
        if (!finalMap[typeName]) {
            finalMap[typeName] = [];
        }
        finalMap[typeName].push({
            "Firstname": firstName,
            "LastName": lastName
        });
    });
    let result = [];
    for (const [key, value] of Object.entries(finalMap)) {
        result.push({
            "Type": key,
            "Names": value
        });
    }
    return result;

}
console.log(processData(data));

答案 5 :(得分:0)

对任何组使用此方法:

const groupBy = function (list, key) {
  return list.reduce((finalList, item) => {
    const group = (finalList[item[key]] = finalList[item[key]] || [])
    group.push(item)
    return finalList
  }, {})
}

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

console.log(groupBy(a, 'Type'))

答案 6 :(得分:0)

我们可以使用 Array.reduce & Object.values 来达到预期的输出。

const a = [{Name:'martha',Surname:'james',Type:'student'},{Name:'Meredith',Surname:'Napier',Type:'Teacher'},{Name:'Julie',Surname:'Schrutt',Type:'student'}];

const groupBy = (data, by) => {
  const result = data.reduce((acc, obj) => {
    const key = obj[by];
    const { Type, Name: Firstname, Surname: Lastname } = obj;
    acc[key] = acc[key] || { Type, Names: []};
    acc[key].Names.push({ Firstname, Lastname });
    return acc;
  }, {});
  return Object.values(result);
}

console.log(groupBy(a, "Type"));
.as-console-wrapper {
  max-height: 100% !important;
}

我们也可以使用 Logical nullish assignment (??=) 代替 acc[obj[by]] = acc[obj[by]] || { Type, Names: []}

const a = [{Name:'martha',Surname:'james',Type:'student'},{Name:'Meredith',Surname:'Napier',Type:'Teacher'},{Name:'Julie',Surname:'Schrutt',Type:'student'}];

const groupBy = (data, by) => {
  const result = data.reduce((acc, obj) => {
    const key = obj[by];
    const { Type, Name: Firstname, Surname: Lastname } = obj;
    acc[key] ??= { Type, Names: []};
    acc[key].Names.push({ Firstname, Lastname });
    return acc;
  }, {});
  return Object.values(result);
}

console.log(groupBy(a, "Type"));
.as-console-wrapper { 
  max-height: 100% !important;
}