如何在反应中映射嵌套的对象数组,一次映射一个子数组项

How to map a nested array of objects, one child array item at a time, in react

我对 React 和 JavaScript 都很陌生,非常感谢对此的一些建议。我想使用 map() 方法遍历如下所示的嵌套数组:

const demos = [
    {
      id : '1',
      name: 'name1',
      dates:  ['jan', 'feb', 'apr']
    }, 
    {
      id : '2',
      name: 'name2',
      dates: ['feb', 'may']
    }
];

我想先映射第一个对象的第一个日期,然后映射第二个日期,依此类推,然后再转到下一个对象,然后根据日期对其进行排序,以理想地实现以下输出:

name1: jan 
name1: feb
name2: feb
name1: apr
name2: may

到目前为止我想出的唯一不太有效的解决方案是:

import * as React from 'react';

const demos = [
    
        {id : '1',
        name: 'name1',
        dates:  ['jan', 'feb', 'apr']
        }, 
        {id : '2',
        name: 'name2',
        dates: ['feb', 'may']
        }
                
];

const counts = ['0','1','2'];

export default function Test() {
        
    return (
      <div>
      {
        counts.map(count => (
          demos.map(demo =>(
            <div key={demo.id}>
              <div>{demo.name}: {demo.dates[count]}</div>
            </div>
           ))
         ))
       }
       </div>
    );
}

这给了我以下输出:

name1: jan
name2: feb
name1: feb
name2: may
name1: apr
name2:

使用 const counts 并没有真正起作用,而且感觉不是正确的开始方式。我怎样才能以好的方式做到这一点,然后按日期排序?

在您的

中执行以下代码 {demo.name}:{`demo.dates.map((e) => {e} )`} 它应该有效。

已排序

const App = () => {
  const demos = [
    { id: "1", name: "name1", dates: ["jan", "feb", "apr"] },
    { id: "2", name: "name2", dates: ["feb", "may"] }
  ];

  const monthIdx = {
    jan: 1,
    feb: 2,
    mar: 3,
    apr: 4,
    may: 5,
    jun: 6,
    jul: 7,
    aug: 8,
    sep: 9,
    oct: 10,
    nov: 11,
    dec: 12
  };

  const sortedDemo = demos
    .map((demo) => {
      return demo.dates.map((date) => ({ [demo.name]: date }));
    })
    .flat()
    .sort((a, b) => {
      const monthA = Object.values(a)[0];
      const monthB = Object.values(b)[0];
      return monthIdx[monthA] - monthIdx[monthB];
    });

  return sortedDemo.map((demo) => {
    const [key] = Object.entries(demo);
    const [name, date] = key;
    return (
      <div>
        {name} - {date}
      </div>
    );
  });
};

没有排序

const demos = [
  { id: "1", name: "name1", dates: ["jan", "feb", "apr"] },
  { id: "2", name: "name2", dates: ["feb", "may"] }
];

return demos.map((demo) => {
  return demo.dates.map((date) => (
    <div>
      {demo.name} - {date}
    </div>
  ));
});

可以使用 stack-snippets 提供可行的代码,如下所示:

const demos = [
    
        {id : '1',
        name: 'name1',
        dates:  ['jan', 'feb', 'apr']
        }, 
        {id : '2',
        name: 'name2',
        dates: ['feb', 'may']
        }
                
];

// const counts = ['0','1','2'];

function Test() {
  const sortHelper = Object.fromEntries(("jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec")
    .split(", ").map((m, idx) => ([m, idx])));

  const transformArr = arr => (
    [...arr].map(({name, dates}) => (
      dates.map(month => ({ name, month }))
    ))
    .flat()
    .sort((a, b) => (sortHelper[a.month] - sortHelper[b.month]))
  );
  return (
    <div>
    {
      transformArr(demos).map(({name, month}) => (
        <div>{name}: {month}</div>
      ))
    }
    </div>
  );
}

ReactDOM.render(
  <div>
    DEMO
    <Test />
  </div>,
  document.getElementById("rd")
);
<div id="rd"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

说明

  • 为了使用“一月、二月、三月...十二月”进行排序,创建了一个 sortHelper 对象
  • 使用 .map 和 de-structure namedates
  • 遍历数组
  • 现在,遍历 dates 以创建一个包含两个属性 namemonth
  • 的对象
  • 此对象与预期目标非常相似
  • 使用.flat()删除嵌套数组
  • 结合使用.sort()sortHelper来提供必要的顺序

也许使用桶排序会有所帮助:

const demos = [
  { id : '1', name: 'name1', dates:  ['jan', 'feb', 'apr'] },
  { id : '2', name: 'name2', dates: ['feb', 'may'] }
];

const month_indexes = {
  'jan': 0, 'feb': 1, 'mar': 2, 'apr': 3, 'may': 4, 'jun': 5,
  'jul': 6, 'aug': 7, 'oct': 8, 'sep': 9, 'nov': 10, 'dec': 11,
};

const get_sorted_entries = (items) =>
  items
    .reduce((acc, item) => {
      item.dates.forEach((date) => {
        // for some reason the below line won't run as acc[month_indexes[date]] ||= [];
        acc[month_indexes[date]] = acc[month_indexes[date]] || [];
        acc[month_indexes[date]].push([item, date]);
      });
      return acc;
    }, [])
    .flat();

const App = () => {
  return (
    <React.Fragment>
      {
        get_sorted_entries(demos).map(([item, month]) => (
          <div key={item.id + '-' + month}>{item.name}: {month}</div>
        ))
      }
    </React.Fragment>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>

这里创建了一个由项目数组组成的数组,顶级数组按月索引。使用 flat() 按月取消索引但保留顺序。