简体   繁体   中英

How to create a new array from array's key value pair?

I need an efficient way to convert this array:

[
    {
      uuid: 1,
      date: '2020-12-25',
      note: 'example note 1',
      time: '12:05:00',
      language: ['english']
    },
    {
      uuid: 2,
      date: '2020-12-25',
      note: 'example note 2',
      time: '12:05:00',
      language: ['french']
    },
    {
      uuid: 3,
      date: '2020-12-26',
      note: 'example note 3',
      time: '12:05:00',
      language: ['spanish']
    },
    {
      uuid: 4,
      date: '2020-12-26',
      note: 'example note 4',
      time: '12:05:00',
      language: ['chinese']
    },
  ]

to this new array grouped by date

[
    {
    date:'2020-12-26',
    details:[
      {
        uuid: 3,
        date: '2020-12-26',
        note: 'example note 3',
        time: '12:05:00',
        language: ['spanish']
      },
      {
        uuid: 4,
        date: '2020-12-26',
        note: 'example note 4',
        time: '12:05:00',
        language: ['chinese']
      },
    ]
  },
    {
    date:'2020-12-25',
    details:[
      {
        uuid: 1,
        date: '2020-12-26',
        note: 'example note 1',
        time: '12:05:00',
        language: ['english']
      },
      {
        uuid: 2,
        date: '2020-12-26',
        note: 'example note 2',
        time: '12:05:00',
        language: ['french']
      },
    ]
  },
  ]

i have tried it using lodash _.groupBy but that is not what i want my array to look like, i tried doing this combining, .filter, .reduce and.map but it is really lengthy and does not look efficient at all

I would use .reduce() with .find() as:

 const data = [{ uuid: 1,date: '2020-12-25',note: 'example note 1',time: '12:05:00',language: ['english']},{uuid: 2,date: '2020-12-25',note: 'example note 2',time: '12:05:00',language: ['french']},{uuid: 3,date: '2020-12-26',note: 'example note 3',time: '12:05:00',language: ['spanish']}, {uuid: 4,date: '2020-12-26',note: 'example note 4',time: '12:05:00',language: ['chinese']},] const result = data.reduce((a, c) => { const found = a.find(e => e.date === c.date); const elem = { uuid: c.uuid, note: c.note, time: c.time, language: c.language }; if (found) { found.details.push(elem); } else { a.push({ date: c.date, details: [elem] }); } return a; }, []); console.log(result)

You can use the reduce function to create groups and assign the values to them:

 const input = [ { uuid: 1, date: '2020-12-25', note: 'example note 1', time: '12:05:00', language: ['english'] }, { uuid: 2, date: '2020-12-25', note: 'example note 2', time: '12:05:00', language: ['french'] }, { uuid: 3, date: '2020-12-26', note: 'example note 3', time: '12:05:00', language: ['spanish'] }, { uuid: 4, date: '2020-12-26', note: 'example note 4', time: '12:05:00', language: ['chinese'] }, ]; const output = input.reduce((result, record) => { if (.result[record.date]) result[record:date] = { date. record,date: details; [] }. result[record.date].details;push(record); return result, }; {}). console;log(output). // If you want it as an array console.log(Object;values(output));

Instead of creating it directly as an array, I create it as an object with the date as the key. This makes it so I don't have to search all of the results for the correct one.

I start by looking if I have an entry for that date. If I don't, I make one.

Then I simply add the record to the details for that entry.

At the end, I convert it to an array if you really need it that way simply by using Object.values() .

Ciao, you could do a lodash chain , then a groupBy follewed by a map . Like this:

 let input = [ { uuid: 1, date: '2020-12-25', note: 'example note 1', time: '12:05:00', language: ['english'] }, { uuid: 2, date: '2020-12-25', note: 'example note 2', time: '12:05:00', language: ['french'] }, { uuid: 3, date: '2020-12-26', note: 'example note 3', time: '12:05:00', language: ['spanish'] }, { uuid: 4, date: '2020-12-26', note: 'example note 4', time: '12:05:00', language: ['chinese'] }, ] console.log( _.chain(input) // Group the elements of Array based on `date` property.groupBy("date").map((value, key) => ({ date: key, details: value })).value() );
 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>

Here is a solution: https://jsfiddle.net/9p1fx3dq/1/

    var a = [
        {
          uuid: 1,
          date: '2020-12-25',
          note: 'example note 1',
          time: '12:05:00',
          language: ['english']
        },
        {
          uuid: 2,
          date: '2020-12-25',
          note: 'example note 2',
          time: '12:05:00',
          language: ['french']
        },
        {
          uuid: 3,
          date: '2020-12-26',
          note: 'example note 3',
          time: '12:05:00',
          language: ['spanish']
        },
        {
          uuid: 4,
          date: '2020-12-26',
          note: 'example note 4',
          time: '12:05:00',
          language: ['chinese']
        },
      ];
      
      function groupBy(key) {
      return function group(array) {
        return array.reduce((acc, obj) => {
          const property = obj[key];
          if (!acc.some(s => s.date === property)){
            acc.push({date: property, details: []});
          }
          var details = acc.find(s => s.date === property).details;
          details.push(obj);
          return acc;
        }, []);
      };
    }
    
    console.log(groupBy('date')(a));

I used new Set to get the distinct values

const array1 = [
  {
    uuid: 1,
    date: "2020-12-25",
    note: "example note 1",
    time: "12:05:00",
    language: ["english"]
  },
  {
    uuid: 2,
    date: "2020-12-25",
    note: "example note 2",
    time: "12:05:00",
    language: ["french"]
  },
  {
    uuid: 3,
    date: "2020-12-26",
    note: "example note 3",
    time: "12:05:00",
    language: ["spanish"]
  },
  {
    uuid: 4,
    date: "2020-12-26",
    note: "example note 4",
    time: "12:05:00",
    language: ["chinese"]
  }
];

const dates = array1.map(x => x.date);
const uniqueDates = [...new Set(dates)];
const result = uniqueDates.map(date => {
  return {
    date: date,
    details: array1.filter(f => f.date === date)
  }
});

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