skip to Main Content

I have an array object which gets populated from database.

dataObj = [
    {
        "id": "1",
        "date": "Tue Nov 07 2023",
        "month": "11",
        "day": "Tuesday",
    },

    {
        "id": "2",
        "date": "Tue Nov 07 2023",
        "month": "11",
        "day": "Tuesday",
    },
    {
        "id": "kGSykTUAd6gcEUmskMu6",
        "date": "Wed Nov 08 2023",
        "month": "11",
        "day": "Wednesday",
    },
   
]

Now I want the UI to be like this-

UI design

The common date is shown as one date on the left and other information on the right.
For example,
First two entries fall on the same date,
so the left should show one date i.e. Nov 7 and the right section should show all id, month, day for Nov 7.

But when I’m comparing the array and converting the duplicate dates as one and then displaying the date, it does not show the right output. The output is –

Nov 7 – id, date, month

Nov 7 – id, date, month

Correct Output should be

   Nov 7  

   id, date, month

   id, date, month

   Nov 8

   id, date, month

JS


let datesArr = []

// Pushing the data in the array.
datesArr.push( doc.data().dates )

// Removing same dates from the datesArr
let duplicates = datesArr.filter( function ( item, index, inputArray )
    {
        return inputArray.indexOf( item ) === index
    } )

    duplicates.sort( ( a, b ) =>
    {
        return a - b
    } )

    for ( let dupes of duplicates )
    {
        let myArr = []
        let dupesDate = new Date( dupes ).toDateString()

        for ( let content of dataObj)
        {
            if ( dupesDate === new Date( content.date).toDateString() )
            {
                myArr.push( content );
            }
        }
        
    }

How do I fix this, I been struggling with this for few days now.

4

Answers


  1. You can try using Array.prototype.reduce():

    const dataObj = [
      {
        "id": "1",
        "date": "Tue Nov 07 2023",
        "month": "11",
        "day": "Tuesday",
      },
      {
        "id": "2",
        "date": "Tue Nov 07 2023",
        "month": "11",
        "day": "Tuesday",
      },
      {
        "id": "kGSykTUAd6gcEUmskMu6",
        "date": "Wed Nov 08 2023",
        "month": "11",
        "day": "Wednesday",
      }
    ];
    
    //grouping the data by 'date'
    const groupedData = dataObj.reduce((acc, curr) => {
      const date = curr.date;
      
      //check if the 'date' already exists in 'acc'
      const existingDate = acc.find(item => item.date === date);
    
      if (existingDate) {
        //if the 'date' already exists, add the current object to its 'items' array
        existingDate.items.push(curr);
      } else {
        //if 'date' doesn't exist, create a new object with 'date' and 'items' array
        acc.push({ date, items: [curr] });
      }
    
      return acc;
    }, []);
    
    groupedData.forEach(group => {
        const groupDiv = document.createElement('div');
        const header = document.createElement('h3');
        const ul = document.createElement('ul');
    
        header.textContent = group.date;
        groupDiv.appendChild(header);
    
        group.items.forEach(item => {
          const li = document.createElement('li');
          li.textContent = `${item.id}, ${item.date}, ${item.month}, ${item.day}`;
          ul.appendChild(li);
        });
    
        groupDiv.appendChild(ul);
        app.appendChild(groupDiv);
    });
    ul {
        list-style: none;
        padding-left: 0;
    }
    <div id="app"></div>
    Login or Signup to reply.
  2. You can use below code snippet to convert it into your expected output,

    // Original data
    const dataObj = [
        {
            "id": "1",
            "date": "Tue Nov 07 2023",
            "month": "11",
            "day": "Tuesday",
        },
        {
            "id": "2",
            "date": "Tue Nov 07 2023",
            "month": "11",
            "day": "Tuesday",
        },
        {
            "id": "kGSykTUAd6gcEUmskMu6",
            "date": "Wed Nov 08 2023",
            "month": "11",
            "day": "Wednesday",
        },
    ];
    
    // Create an object to store the result
    const dateWiseObject = {};
    
    // Iterate through the original array and group objects by date
    dataObj.forEach(item => {
        const date = item.date;
        if (!dateWiseObject[date]) {
            dateWiseObject[date] = [];
        }
        dateWiseObject[date].push(item);
    });
    
    // Convert the date-wise object into an array
    const resultArray = Object.keys(dateWiseObject).map(date => ({
        date: date,
        items: dateWiseObject[date],
    }));
    
    console.log(JSON.stringify(resultArray));
    
    Login or Signup to reply.
  3. You can try the below code:

    const dataObj = [{
        "id": "1",
        "date": "Tue Nov 07 2023",
        "month": "11",
        "day": "Tuesday",
      },
      {
        "id": "2",
        "date": "Tue Nov 07 2023",
        "month": "11",
        "day": "Tuesday",
      },
      {
        "id": "kGSykTUAd6gcEUmskMu6",
        "date": "Wed Nov 08 2023",
        "month": "11",
        "day": "Wednesday",
      },
    ];
    
    // Group data by date
    const groupedData = dataObj.reduce((acc, obj) => {
      const dateStr = new Date(obj.date).toDateString();
      if (!acc[dateStr]) {
        acc[dateStr] = [];
      }
      acc[dateStr].push(obj);
      return acc;
    }, {});
    
    const app = document.getElementById("app");
    
    for (const date in groupedData) {
      const dateGroup = document.createElement("div");
      dateGroup.classList.add("date-group");
    
      const dateElement = document.createElement("div");
      dateElement.classList.add("date");
      dateElement.textContent = date;
      dateGroup.appendChild(dateElement);
    
      for (const item of groupedData[date]) {
        const itemElement = document.createElement("div");
        itemElement.textContent = `id: ${item.id}, month: ${item.month}, day: ${item.day}`;
        dateGroup.appendChild(itemElement);
      }
    
      app.appendChild(dateGroup);
    }
    .date-group {
      border: 1px solid #ccc;
      padding: 10px;
      margin: 10px 0;
    }
    
    .date {
      font-weight: bold;
      margin-bottom: 5px;
    }
    <div id="app"></div>
    Login or Signup to reply.
  4. Instead of creating intermediate variables (constants) and DOM objects and appending them together you could also do it with a single .innerHTML assignment. The simplified algorithm for grouping below will work if gigs with the same date appear consecutively. Knowing that the data is taken from a database this condition can be easily achieved by sorting by date.

    const dataObj = [
      {
        "id": "1",
        "date": "Tue Nov 07 2023",
        "month": "11",
        "day": "Tuesday",
      },
      {
        "id": "2",
        "date": "Tue Nov 07 2023",
        "month": "11",
        "day": "Tuesday",
      },
      {
        "id": "kGSykTUAd6gcEUmskMu6",
        "date": "Wed Nov 08 2023",
        "month": "11",
        "day": "Wednesday",
      }
    ];
    
    //grouping the data by 'date'
    const grp = dataObj.reduce((acc, curr) => {
      if(acc.last?.[0]?.date==curr.date) {
        // 'date' already exists: add the current object to the acc.last array:
        acc.last.push(curr);
      } else {
        // create a new array in acc:
        acc.push(acc.last=[curr]);
      }
      return acc;
    }, []);
    // console.log(grp);
    
    document.getElementById("app").innerHTML = grp.map(gigs =>
        `<div><h3>${gigs[0].date}</h3><ul>`
        +gigs.map(gig => `<li>${Object.values(gig).join(", ")}</li>`).join("n")+"</ul>").join("n")+"</div>";
    ul {
        list-style: none;
        padding-left: 0;
    }
    <div id="app"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search