#javascript #arrays #reactjs #gatsby #array.prototype.map
#javascript #массивы #reactjs #гэтсби #array.prototype.map
Вопрос:
let array = this.props.data.allGoogleSheetSpacesRow.edges;
const results = [...array.reduce((r, e) => {
let k = `${e.node.twitter}`;
if(!r.has(k)) r.set(k, {...e, count: 1})
else r.get(k).count
return r;
}, new Map)]
Я использую reduce, чтобы получить количество повторяющихся имен пользователей Twitter в моем массиве для создания таблицы лидеров следующим образом:
- Имя пользователя в Twitter: 5
- Имя пользователя в Twitter: 4
- Имя пользователя в Twitter: 2
let leaderboard = results;
console.log(leaderboard);
return (
{leaderboard.map((item, index) => (
<div key={index}>
{item.value.map((c, i) => (
<div key={i}>
<h3>{c.count}</h3>
<h3>{c.node.twitter}</h3>
<hr />
</div>
))}
</div>
))}
)
Я пытаюсь отобразить поверх карты, чтобы отобразить данные, но я не уверен, как это сделать. Я получаю Cannot read property 'map' of undefined
. Что я делаю не так?
Итак, дерево, похоже, идет массив -> array -> object, но я не уверен, что мне нужно сделать, чтобы отобразить это.
Ответ №1:
Для начала загляните в документацию по карте. Обратите внимание, что доступные методы включают entries
, keys
, values
и forEach
. Метода map не существует (хотя можно утверждать, что он должен быть).
Также обратите внимание, что map является итерируемым, поэтому вы можете выполнить for (let [key, value] of map){…}
(что практически то же самое, что вызвать .forEach(…)
or .entries().forEach(…)
).
Однако, что вы, вероятно, хотите, так это Array.from(map.entries()).map(…)
или [...map.entries()].map(…)
. .entries()
возвращает итератор карты из [key, value]
пар, которые могут быть преобразованы в массив, у которого есть .map(…)
метод.
итак, ваш код довольно близок:
return (
<div>{Array.from(leaderboard.entries()).map(([key, value]) => (
<div key={key}>
<div>
<h3>{value.count}</h3>
<h3>{value.node.twitter}</h3>
<hr />
</div>
</div>
))}</div>
)
Комментарии:
1. Есть идеи, почему я получаю
leaderboard.entries(...).map is not a function
?2. Хм, какую версию javascript / браузера вы используете (или на какую версию вы переходите с помощью babel)? Потому что похоже, что вы получаете не карту в качестве значения в результатах, а скорее массив с картой в качестве первого значения. попробуйте
console.log(leaderboard instanceof Array)
иconsole.log(leaderboard instanceof Map)
.3. Кроме того, вы можете захотеть удалить
[...
…]
из aroundd вашего вызова reduce, если вы хотите продолжать использовать карту, а не преобразовывать ее в массив.[...map]
в значительной степени эквивалентно вызовуmap.entries()
в достаточно новых версиях javascript. (Что, возможно, и было вашим намерением …)4. Я использую файл Gatsby’s .babelrc, который, как я полагаю, совпадает с текущей версией React. clg возвращает
false
для экземпляра Array иtrue
для экземпляра Map. Когда яconsole.log(leaderboard.entries())
возвращаюMapIterator {"mmckvr" => {…}, "shylands" => {…}, "null" => {…}, "mccrum" => {…}, "barrymcgee" => {…}, …} __proto__: Map Iterator [[IteratorHasMore]]: true [[IteratorIndex]]: 0 [[IteratorKind]]: "entries" [[Entries]]: Array(8) 0: {"mmckvr" => Object} ... length: 8
, понятия не имею, почему это не работает5. О, хм… Я был уверен, что entries — это массив, но нет, это итератор карты, и у него нет
map
метода. Ну,Array.from(…)
или[...map]
это следует исправить…
Ответ №2:
Вы можете перебирать ключи вашей карты:
return (
{[...leaderboard.keys()].map(key => (
<div key={key}>
<h3>{leaderboard.get(key).count}</h3>
<h3>{leaderboard.get(key).node.twitter}</h3>
</div>
))}
);
Проверьте этот codesandbox:https://codesandbox.io/s/o4v0695n5q
Комментарии:
1. Хм, я получаю
leaderboard.get() is not a function
, когда пытаюсь это сделать. Есть идеи, почему?