A simple solution is to use reduce() without second argument and without spreading the previous result:
class List extends React.Component {
render() {
<div>
{this.props.data
.map(t => <span>{t}</span>)
.reduce((prev, curr) => [prev, ', ', curr])}
</div>
}
}
Without second argument, reduce() will start at index 1 instead of 0, and React is perfectly happy with nested arrays.
As said in the comments, you want to only use this for arrays with at least one item, because reduce() without second argument will throw with an empty array. Normally this should not be a problem, since you want to display a custom message saying something like 'this is empty' for empty arrays anyway.
Update for Typescript
You can use this in Typescript (without type-unsafe any) with a React.ReactNode type parameter on .map():
class List extends React.Component {
render() {
<div>
{this.props.data
.map<React.ReactNode>(t => <span>{t}</span>)
.reduce((prev, curr) => [prev, ', ', curr])}
</div>
}
}
Answer from Maarten ter Horst on Stack OverflowA simple solution is to use reduce() without second argument and without spreading the previous result:
class List extends React.Component {
render() {
<div>
{this.props.data
.map(t => <span>{t}</span>)
.reduce((prev, curr) => [prev, ', ', curr])}
</div>
}
}
Without second argument, reduce() will start at index 1 instead of 0, and React is perfectly happy with nested arrays.
As said in the comments, you want to only use this for arrays with at least one item, because reduce() without second argument will throw with an empty array. Normally this should not be a problem, since you want to display a custom message saying something like 'this is empty' for empty arrays anyway.
Update for Typescript
You can use this in Typescript (without type-unsafe any) with a React.ReactNode type parameter on .map():
class List extends React.Component {
render() {
<div>
{this.props.data
.map<React.ReactNode>(t => <span>{t}</span>)
.reduce((prev, curr) => [prev, ', ', curr])}
</div>
}
}
You can use reduce to combine multiple elements of an array:
React.createClass({
render() {
<div>
this.props.data
.map(t => <span>t</span>)
.reduce((accu, elem) => {
return accu === null ? [elem] : [...accu, ',', elem]
}, null)
</div>
}
})
This initializes the accumulator with null, so we can wrap the first item in an array. For each following element in the array, we construct a new array that contains all previous elements using the ...-operator, add the separator and then the next element.
Array.prototype.reduce()
You can also use reduce to insert the separator between every element of the array:
render() {
let myArray = [1,2,3];
return (
<div>
{
myArray
.map(item => <div>{item}</div>)
.reduce((acc, x) => acc === null ? [x] : [acc, ' | ', x], null)
}
</div>
);
}
or using fragments:
render() {
let myArray = [1,2,3];
return (
<div>
{
myArray
.map(item => <div>{item}</div>)
.reduce((acc, x) => acc === null ? x : <>{acc} | {x}</>, null)
}
</div>
);
}
You can also do it by combining .reduce and React fragments.
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>
How to merge two array of objects with reactjs?
Perform .join on value in array of objects
How to join fields of an array of objects in javascript/typescript - Stack Overflow
How to using array.prototype.join in reactjs - javascript
You can use spread operator to merge two array.
var a = [{fname : 'foo'}]
var b = [{lname : 'bar'}]
var c = [...a, ...b] // output [{fname : 'foo'},{lname : 'bar'}]
Because you are making an HTTP call to your server, it takes some time to fetch the data. Instead of setting events state directly, you should wait for the response of your HTTP call. Your code should be like this:
componentDidMount() {
fetch("url")
.then(Response => Response.json())
.then(data => {
let evts = data;
for (let i = 0; i < evts.length; i++) {
evts[i].start = moment(evts[i].start).toDate();
evts[i].end = moment(evts[i].end).toDate();
this.state.evt1.push(evts[i])
}
this.setState({
evt1: evts,
prevEvents: evts
})
})
.then(() => {
console.log(this.state.evt1)
const cachedHits = JSON.parse(localStorage.getItem('Evènements'))
console.log(cachedHits)
for (let j = 0; j < cachedHits.length; j++) {
cachedHits[j].start = moment(cachedHits[j].start).toDate();
cachedHits[j].end = moment(cachedHits[j].end).toDate();
this.state.evt2.push(cachedHits[j])
}
this.setState({
evt2: this.state.evt2
})
this.setState({
events: [...this.state.evt1, ...this.state.evt2]
})
console.log(this.state.events)
});
}
I also recommend you to have a catch block in your promise chain to handle errors.
If you want to map objects to something (in this case a property). I think Array.prototype.map is what you're looking for if you want to code functionally.
(fiddle)
If you want to support older browsers, that are not ES5 compliant you can shim it (there is a polyfill on the MDN page above). Another alternative would be to use underscorejs's pluck method:
var users = [
{name: "Joe", age: 22},
{name: "Kevin", age: 24},
{name: "Peter", age: 21}
];
var result = _.pluck(users,'name').join(",")
Well you can always override the toString method of your objects:
var arr = [
{name: "Joe", age: 22, toString: function(){return this.name;}},
{name: "Kevin", age: 24, toString: function(){return this.name;}},
{name: "Peter", age: 21, toString: function(){return this.name;}}
];
var result = arr.join(", ");
console.log(result);
Before join you need map array
const array = [
{ a: '1', b: '2' },
{ a: '3', b: '4' },
];
const result = array.map(_ => _.a).join(', ');
console.log(result);
In order to perform this through For loop.
result = [];
const array = [{ a: '1', b: '2' }, { a: '3', b: '4' }];
array.forEach(elm => result.push(elm.a));
console.log(result.join(", "));
// 1, 3
The spread operator is kinda cool.
this.results = [ ...this.results, ...data.results];
The spread operator allows you to easily place an expanded version of an array into another array.
You can read about spread operator here.
I think that you should use rather the following:
data => {
this.results = this.results.concat(data.results);
this._next = data.next;
},
From the concat doc:
The concat() method returns a new array comprised of the array on which it is called joined with the array(s) and/or value(s) provided as arguments.