0

I am using redux and I am working on receiving data about membership information from action and processing it from components.

And try to process the data to a table.

I took data from user action and created a table through map functions... The incoming data contains

Data received as action ....

[{create_date : "2020-02-16T03:00:00Z", id:"test"},
{create_date : "2020-02-16T01:00:00Z", id:"test1"},
{create_date : "2020-02-14T03:00:00Z", id:"test2"},
{create_date : "2020-02-14T01:00:00Z", id:"test3"},
{create_date : "2020-02-14T00:00:01Z", id:"test4"},
{create_date : "2020-02-13T03:00:00Z", id:"test5"},
...] 

As you can see, only create_date id is included.

I would like to order them by date and number them in order by next day after day.

For example, would like to print like this.

index    create_date           id   
2        2020-02-16T03:00:00Z  test
1        2020-02-16T01:00:00Z  test1

3        2020-02-14T03:00:00Z  test2
2        2020-02-14T01:00:00Z  test3
1        2020-02-14T00:00:01Z  test4

1        2020-02-13T03:00:00Z  test5

How to insert index using if statement when using map function in react??

Mycode

    render() {
        const {user_list} = this.props;
        console.log(user_list);
        return (
            <div className="animated fadeIn">
                <Row>
                    <Col xl={12}>
                        <Card>
                            <CardHeader>
                                <i className="fa fa-align-justify"></i>userlist
                            </CardHeader>
                            <CardBody>
                                <Search searchUser={this.searchUser}/>
                                <Table responsive hover>
                                    <thead>
                                    <tr><th scope="col">Index</th>
                                        <th scope="col">create_time</th>
                                        <th scope="col">id/name</th>
                                    </tr>
                                    </thead>
                                    <tbody>
                                    {user_list.length > 0 && user_list.map((item, index) => (
                                        <tr key={item.id.toString()}>
                                            <td>{index}</td> //<<Does this change by date index.. if statement?
                                            <td className={'datetime'}>
                                                {item.hasOwnProperty('create_date') &&
                                                    <div>
                                                        {moment(item.create_date).format('YYYY-MM-DD')}<br/>
                                                        {moment(item.create_date).format('HH:mm')}
                                                    </div>
                                                }
                                            </td>
                                            <td scope="row">
                                                    {item.displayName}
                                            </td>

                                        </tr>
                                    ))}
                                    </tbody>
                                </Table>
                            </CardBody>
                        </Card>
                    </Col>
                </Row>


            </div>
        )
    }

....

6
  • Is the question how to sort, or how to render the index from map? It's not clear what you are asking here. Commented Feb 16, 2020 at 8:40
  • Is it possible for me to do the output I want with the data that I have less? from map Commented Feb 16, 2020 at 8:47
  • not directly from map, unless you pre sort the data, and not by leveraging the index from the array directly, you want to render a synthetic index here. Group your data, sort each group, then you can render each group and print the index as it'll be relative to the group. Worth considering a utility library like lodash, lots of useful functions including groupBy. Commented Feb 16, 2020 at 8:52
  • .map(item, index) {...} gives you access to the array item and that item’s index each iteration. So your index would be 0, 1, 2, 3, 4, 5 for your array. The “index” column you have created here is not the index of the array. Probably you should name it something else like “daily entries” or something. Is your action data always sorted (as shown)? Or does it need to be sorted? Commented Feb 16, 2020 at 8:54
  • @AlexL action data is always sorted recive. So what's the best way to give index and build a table as I intended? Commented Feb 16, 2020 at 9:02

2 Answers 2

2

Elaborate on comments of @James. I just changed a little bit.

You can group them first by date. And then flat it to a list you want. Plain javascirpt version:

let data = [{create_date : "2020-02-16T03:00:00Z", id:"test"},
{create_date : "2020-02-16T01:00:00Z", id:"test1"},
{create_date : "2020-02-14T03:00:00Z", id:"test2"},
{create_date : "2020-02-14T01:00:00Z", id:"test3"},
{create_date : "2020-02-14T00:00:01Z", id:"test4"},
{create_date : "2020-02-13T03:00:00Z", id:"test5"},
]

let groups = {}
for (let e of data.reverse()) {
  let date = e.create_date.slice(0, 10)
  if (groups[date]) {
    let group = groups[date];
    group.push({ index: group.length + 1, ...e });
  } else {
    groups[date] = [{ index: 1, ...e }]
  }
}

const dates = Object.keys(groups).reverse()
const flatten = []
for (let date of dates) {
  flatten.push(...(groups[date].reverse()))
}

console.log(flatten)

flatten should be logged as:

[ { index: 2, create_date: '2020-02-16T03:00:00Z', id: 'test' },
  { index: 1, create_date: '2020-02-16T01:00:00Z', id: 'test1' },
  { index: 3, create_date: '2020-02-14T03:00:00Z', id: 'test2' },
  { index: 2, create_date: '2020-02-14T01:00:00Z', id: 'test3' },
  { index: 1, create_date: '2020-02-14T00:00:01Z', id: 'test4' },
  { index: 1, create_date: '2020-02-13T03:00:00Z', id: 'test5' } ]

You should be able to render that directly in a map. Though I think it's better to store the flatten list as state or in redux store so that it won't do the transformation on every rerender.

Sign up to request clarification or add additional context in comments.

Comments

2

Here's a minimal verifiable complete working demo (https://codepen.io/Alexander9111/pen/rNVeyyY), taking part of the excellent grouping and flattening function from @bedew and then sorting it into date and "index" to give the following output (in React CodePen):

enter image description here

JS:

const action_data = [
  {create_date : "2020-02-16T03:00:00Z", id:"test"},
  {create_date : "2020-02-16T01:00:00Z", id:"test1"},
  {create_date : "2020-02-14T03:00:00Z", id:"test2"},
  {create_date : "2020-02-14T01:00:00Z", id:"test3"},
  {create_date : "2020-02-14T00:00:01Z", id:"test4"},
  {create_date : "2020-02-13T03:00:00Z", id:"test5"}
];

const Demo = (props) => {
  console.log(props.action)

  let groups = {}
  for (let e of props.action.reverse()) {
    let date = e.create_date.slice(0, 10)
    if (groups[date]) {
      let group = groups[date];
      group.push({ index: group.length + 1, ...e });
    } else {
      groups[date] = [{ index: 1, ...e }]
    }
  }

  const dates = Object.keys(groups).reverse()
  const flatten = []
  for (let date of dates) {
    flatten.push(...(groups[date].reverse()))
  }
  const user_list = flatten.sort((a,b) => {
    if (moment(b.create_date).diff(moment(a.create_date), 'days') == 0){
      return (b.index - a.index);
    } else {
      return 0;
    }      
  });
  console.log(user_list);

  return(
    <div>
    <table>
      <thead>
        <tr>
          <th scope="col">Index</th>
          <th scope="col">create_time</th>
          <th scope="col">id/name</th>
        </tr>
      </thead>
      <tbody>
        {user_list.length > 0 && user_list.map((item, index) => (
          <tr key={item.id.toString()}>
            <td>{item.index}</td>
            <td className={'datetime'}>
              {item.hasOwnProperty('create_date') &&
                <div>
                  {moment(item.create_date).format('YYYY-MM-DD') + "  "+ moment(item.create_date).format('HH:mm')}
                </div>
              }
            </td>
            <td scope="row">
              {item.id}
            </td>
          </tr>
        ))}
      </tbody>
    </table>
    </div>
  )
}

ReactDOM.render(
  <Demo action={action_data}/>,
  document.getElementById('root')
);

Important is the sort function:

const user_list = flatten.sort((a,b) => {
    if (moment(b.create_date).diff(moment(a.create_date), 'days') == 0){
      return (b.index - a.index);
    } else {
      return 0;
    }      
  });

If the dates are not the same day, then don't sort, but if they are the same day then sort on the "index" created in the flatten array earlier.

Again demo here: https://codepen.io/Alexander9111/pen/rNVeyyY

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.