Есть способ сделать array.join в реакции
Я хотел бы добавить разделитель между каждым элементом массива, используя синтаксис типа array.join.
Что-то вроде следующего:
render() {
let myArray = [1,2,3];
return (<div>
{myArray.map(item => <div>{item}</div>).join(<div>|</div>)}
</div>);
}
У меня есть работа с использованием метода lodash.transform, но он кажется уродливым, я хотел бы просто сделать .join(<some-jsx>)
и вставить разделитель между каждым элементом.
Ответы
Ответ 1
Попытка с .join с React Elements, вероятно, не выйдет за вас. Это приведет к результату, который вам нужно описать.
render() {
let myArray = [1,2,3];
return (
<div>
{myArray.map((item, i, arr) => {
let divider = i<arr.length-1 && <div>|</div>;
return (
<span key={i}>
<div>{item}</div>
{divider}
</span>
)
})}
</div>
);
}
Ответ 2
Вы также можете использовать reduce
для вставки разделителя между каждым элементом массива:
render() {
let myArray = [1,2,3];
return (
<div>
{
myArray
.map(item => <div>{item}</div>)
.reduce((acc, x) => acc === null ? [x] : [acc, ' | ', x], null)
}
</div>
);
}
Ответ 3
Btw. вы также можете выполнять функции для реагирования. Моим подходом были бы .forEach
пары push(value); push(glue);
, а затем pop()
конечный клей...
function() {
joinLike = [];
originData.forEach(function(v,i) {
joinLike.push(v);
joinLike.push(<br>);
})
joinLike.pop();
return joinLike;
}
Ответ 4
reduce
здесь избыток, а оптимальная функция - flatMap
(map
+ flatten
, иногда называемая concatMap
или chain
).
<p className="conceps inline list">
{flatMap((concept, i) =>
[concept, <span key={i} className="separator">•</span>]
, lesson.concepts).slice(-1)}
</p>
генерирует что-то вроде
Функция • Тип функции • Функция более высокого порядка • Частичное приложение
P.S.
Для Рамды это R.addIndex(R.chain)
вместо flatMap
выше.
Для vanilla JS предлагается предложение Stage-2 (atm) для добавления как flatten
, так и flatMap
: https://tc39.github.io/proposal-flatMap/
Ответ 5
Вы также можете сделать это, комбинируя фрагменты .reduce
и React
.
function jsxJoin (array, str) {
return array.length > 0
? array.reduce((result, item) => <>{result}{str}{item}</>)
: null;
}
function jsxJoin (array, str) {
return array.length > 0
? array.reduce((result, item) => <React.Fragment>{result}{str}{item}</React.Fragment>)
: null;
}
const element = jsxJoin([
<strong>hello</strong>,
<em>world</em>
], <span> </span>);
ReactDOM.render(element, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Ответ 6
Чтобы создать запрошенное решение, в React объединение, похоже, не работает, поэтому с картой и сокращением вы можете сделать это следующим образом:
render() {
let myArray = [1, 2, 3];
return (
<div>
{myArray
.map(item => <div>{item}</div>)
.reduce((result, item) => [result, <div>|</div>, item])}
</div>
);
}
Ответ 7
Вы также можете попробовать flatMap()
. Поддержка браузера идет, но до тех пор вы могли бы использовать polyfill. Единственным недостатком является то, что вам придется потерять последний элемент.
Например.
{myArray.flatMap(item => [<div>{item}</div>, <div>|</div>]).slice(0, -1)}
Или же
{myArray.flatMap((item, i) => [
<div>{item}</div>,
i < myArray.length - 1 ? <div>|</div> : null
])
Ответ 8
Вы можете использовать такую функцию, как эта
function componentsJoin(components, separator) {
return components.reduce(
(acc, curr) => (acc.length ? [...acc, separator, curr] : [curr]),
[]
);
}
Или можете использовать пакет, найденный этим https://www.npmjs.com/package/react-join