Michael
Michael

Reputation: 439

How to create new array of object with new key in each object for section list

I have some feature to develop.

I have array with data that contains tasks. Each task have taskEndDate key with value formatted as ( YYYY-MMM-DD ) and it looks like :

[
    {
        "id": "1616193050660",
        "isExpired": false,
        "isFinished": false,
        "subTasks": [
            "Voda redbull ",
            "Wiskey Coca-Cola "
        ],
        "taskCreationDate": "2021-Jun-12",
        "taskEndDate": 2021-Jun-15,
        "taskTitle": "Drink somethig",
        "taskType": "BAR"
    },
    {
        "id": "1616193050660",
        "isExpired": false,
        "isFinished": false,
        "subTasks": [
            "Voda redbull ",
            "Wiskey Coca-Cola "
        ],
        "taskCreationDate": "2021-Jun-12",
        "taskEndDate": 2021-Jun-15,
        "taskTitle": "Drink somethig",
        "taskType": "BAR"
    },
 {
        "id": "1616193050660",
        "isExpired": false,
        "isFinished": false,
        "subTasks": [
            "Voda redbull ",
            "Wiskey Coca-Cola "
        ],
        "taskCreationDate": "2021-Jun-13",
        "taskEndDate": 2021-Jun-18,
        "taskTitle": "Drink somethig",
        "taskType": "BAR"
    }
]

I need to create new array of object that will in next format.

newArray = [{
    title: taskEndDate,
    data: all tasks that contain same taskEndDate as title
}];

As you can see, the taskEndDate can be same value in few tasks, so I won't to render the title each times, but only once.

For now , I'm doing it hardcoded and then putting the sortedData to <SectionList/>:

const sortedData = [
        {
            title: 'Previous',
            data: data.filter((task) => moment().format('YYYY-MM-DD') > moment(task.taskEndDate).format('YYYY-MM-DD')),
        },
        {
            title: `Today - ${moment().format('MMMM-DD')}`,
            data: data.filter((task) => moment().format('YYYY-MM-DD') === moment(task.taskEndDate).format('YYYY-MM-DD')),
        },
        {
            title: 'Tomorrow',
            data: data.filter((task) => moment().add(1, 'd').format('YYYY-MM-DD') === moment(task.taskEndDate).format('YYYY-MM-DD')),
        },
        {
            title: moment().add(2, 'd').format('YYYY-MM-DD'),
            data: data.filter((task) => moment().add(2, 'd').format('YYYY-MM-DD') === moment(task.taskEndDate).format('YYYY-MM-DD')),
        },
        {
            title: 'Future',
            data: data.filter((task) => moment().add(2, 'd').format('YYYY-MM-DD') < moment(task.taskEndDate).format('YYYY-MM-DD')),
        },
    ];

How can I do it generic ti all dates?

Upvotes: 0

Views: 72

Answers (3)

Imam
Imam

Reputation: 1306

Let's consider the data array is sorted by the taskEndDate, then we can achieve grouping the data by taskEndDate as below:

const data = [{..}, {...}] // data array sorted by `taskEndDate`. If not needs to sort the array by taskEndDate before running the forEach loop

let sortedData = []
let length = 0 // length of sortedData

data.forEach(task => {
  if(sortedData[length - 1] && task.taskEndDate === sortedData[length - 1].title){
    sortedData[length - 1].data.push(task);
  }
  else{
    sortedData.push({title: task.taskEndDate, data: [task] })
    ++length;
  }
})

console.log(sortedData)

Output:

[
  {
    title: '2021-Jun-15',
    data: [
      {
        id: '1616193050660',
        ...,
        taskCreationDate: '2021-Jun-12',
        taskEndDate: '2021-Jun-15',
      },
      {
        id: '1616193050660',
        ...,
        taskCreationDate: '2021-Jun-12',
        taskEndDate: '2021-Jun-15',
      }
    ]
  },
  {
    title: '2021-Jun-18',
    data: [
      {
        id: '1616193050660',
        ...,
        taskCreationDate: '2021-Jun-13',
        taskEndDate: '2021-Jun-18',
      }
    ]
  }
]

Upvotes: 2

Michael
Michael

Reputation: 439

Ok, I fixed it within the next way :

const getSortedArrayWithTitles = () => {

        if (data.length) {
            let sortedArray = [
                {
                    title: moment(data[0].taskEndDate).format(appConfig.DAYS_FORMAT),
                    data: data.filter((task) => moment(task.taskEndDate).format(appConfig.DAYS_FORMAT) === moment(data[0].taskEndDate).format(appConfig.DAYS_FORMAT))
                }
            ];

            for (let i = 0, j = 0; i < data.length; i++) {
                if (!sortedArray[j].title.includes(moment(data[i].taskEndDate).format(appConfig.DAYS_FORMAT))) {
                    sortedArray.push(
                        {
                            title: moment(data[i].taskEndDate).format(appConfig.DAYS_FORMAT),
                            data: data.filter((task) => moment(task.taskEndDate).format(appConfig.DAYS_FORMAT) === moment(data[i].taskEndDate).format(appConfig.DAYS_FORMAT))
                        }
                    );
                    j++;
                }
            }
            return sortedArray;
        }
    };

I'm pretty sure that it is not a best way to use for loop, but It's working fine. Maybe you guys have a better way?

Upvotes: 0

crispengari
crispengari

Reputation: 9321

I'm not sure if this is what you want. Let me know if this is what you want.

  const data = [
    {
      id: "1616193050660",
      isExpired: false,
      isFinished: false,
      subTasks: ["Voda redbull ", "Wiskey Coca-Cola "],
      taskCreationDate: "2021-Jun-12",
      taskEndDate: "2021-Jun-15",
      taskTitle: "Drink somethig",
      taskType: "BAR",
    },
    {
      id: "1616193050660",
      isExpired: false,
      isFinished: false,
      subTasks: ["Voda redbull ", "Wiskey Coca-Cola "],
      taskCreationDate: "2021-Jun-12",
      taskEndDate: "2021-Jun-15",
      taskTitle: "Drink somethig",
      taskType: "BAR",
    },
    {
      id: "1616193050660",
      isExpired: false,
      isFinished: false,
      subTasks: ["Voda redbull ", "Wiskey Coca-Cola "],
      taskCreationDate: "2021-Jun-13",
      taskEndDate: "2021-Jun-18",
      taskTitle: "Drink somethig",
      taskType: "BAR",
    },
  ];
  const sortedData = data.map((data_) => {
    return {
      title: data_.taskEndDate,
      data: data.filter((_task) => data_.taskEndDate === _task.taskEndDate),
    };
  });
  console.log(sortedData);

Upvotes: 0

Related Questions