原文地址: https://codeburst.io/writing-javascript-with-map-reduce-980602ff2f2f
做者: Shivek Khurana
简介:本文是一份编写优雅、简洁和函数式ES6代码的快捷清单。
现现在JavaScript有许多问题,可是词法并非其中之一。不论是三元运算符,仍是map/reduce等ES6方法,亦或是扩展运算符(...)都是很是强大的工具。 javascript
除了可以保证可读性以及准确性,这些方法还有助于实现不可变性,由于这些方法会返回新的数据,而处理前的原始数据并不会被修改。这样的处理风格很适合redux以及Fractal。java
话很少说,让咱们开始吧。react
当你想要将多个数据放进一个实例中时,你可使用一个reducer。git
const posts = [ {id: 1, upVotes: 2}, {id: 2, upVotes: 89}, {id: 3, upVotes: 1} ]; const totalUpvotes = posts.reduce((totalUpvotes, currentPost) => totalUpvotes + currentPost.upVotes, //reducer函数 0 // 初始化投票数为0 ); console.log(totalUpvotes)//输出投票总数:92
传给reduce的第一个参数函数还能够增长2个参数:github
collection.reduce( (accumulator, currentElement, currentIndex, collectionCopy) => {/*function body*/}, initialAccumulatorValue );
map方法的做用在于处理流式数据,好比数组。咱们能够把它想象成全部元素都要通过的一个转换器。redux
const integers = [1, 2, 3, 4, 6, 7]; const twoXIntegers = integers.map(i => i*2); // twoXIntegers如今是 [2, 4, 6, 8, 12, 14],而integers不发生变化。
find返回数组或相似结构中知足条件的第一个元素。数组
const posts = [ {id: 1, title: 'Title 1'}, {id: 2, title: 'Title 2'} ]; // 找出id为1的posts const title = posts.find(p => p.id === 1).title;
filter方法能够筛除数组和相似结构中不知足条件的元素,并返回知足条件的元素组成的数组。数据结构
const integers = [1, 2, 3, 4, 6, 7]; const evenIntegers = integers.filter(i => i%2 === 0); // evenIntegers的值为[2, 4, 6]
若是你要建立一个无限滚动的ui组件(好比本文后面提到的例子),可使用扩展运算符这个很是有用的词法。app
const books = ['Positioning by Trout', 'War by Green']; const newBooks = [...books, 'HWFIF by Carnegie']; // newBooks are now ['Positioning by Trout', 'War by Green', 'HWFIF // by Carnegie']
若是须要实现用户从购物车中删除物品,可是又不想破坏原来的购物车列表,可使用filter方法。函数
const myId = 6; const userIds = [1, 5, 7, 3, 6]; const allButMe = userIds.filter(id => id !== myId); // allButMe is [1, 5, 7, 3]
译者注:这里我猜想做者是不想修改原来的数组因此使用的filter,可是不能理解为何要举购物车的例子。
const books = []; const newBook = {title: 'Alice in wonderland', id: 1}; const updatedBooks = [...books, newBook]; //updatedBooks的值为[{title: 'Alice in wonderland', id: 1}]
books这个变量咱们没有给出定义,可是没关系,咱们使用了扩展运算符,它并不会所以失效。
const user = {name: 'Shivek Khurana'}; const updatedUser = {...user, age: 23}; //updatedUser的值为:{name: 'Shivek Khurana', age: 23}
const dynamicKey = 'wearsSpectacles'; const user = {name: 'Shivek Khurana'}; const updatedUser = {...user, [dynamicKey]: true}; // updatedUser is {name: 'Shivek Khurana', wearsSpectacles: true}
const posts = [ {id: 1, title: 'Title 1'}, {id: 2, title: 'Title 2'} ]; const updatedPosts = posts.map(p => p.id !== 1 ? p : {...p, title: 'Updated Title 1'} ); /* updatedPosts is now [ {id: 1, title: 'Updated Title 1'}, {id: 2, title: 'Title 2'} ]; */
const posts = [ {id: 1, title: 'Title 1'}, {id: 2, title: 'Title 2'} ]; const postInQuestion = posts.find(p => p.id === 2); // postInQuestion now holds {id: 2, title: 'Title 2'}
译者注:奇怪啊,这不就是以前find的简单实践吗?
const user = {name: 'Shivek Khurana', age: 23, password: 'SantaCl@use'}; const userWithoutPassword = Object.keys(user) .filter(key => key !== 'password') .map(key => {[key]: user[key]}) .reduce((accumulator, current) => ({...accumulator, ...current}), {} ) ; // userWithoutPassword becomes {name: 'Shivek Khurana', age: 23}
感谢Kevin Bradley提供了一个更优雅的方法:
const user = {name: 'Shivek Khurana', age: 23, password: 'SantaCl@use'}; const userWithoutPassword = (({name, age}) => ({name, age}))(user);
他还表示这个方法在对象属性更少时也能发挥做用。
你也许几乎遇不到这个需求,可是有时候在别的地方会给你一点启发。
const params = {color: 'red', minPrice: 8000, maxPrice: 10000}; const query = '?' + Object.keys(params) .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]) ) .join('&') ; // encodeURIComponent将对特殊字符进行编码。 // query is now "color=red&minPrice=8000&maxPrice=10000"
const posts = [ {id: 13, title: 'Title 221'}, {id: 5, title: 'Title 102'}, {id: 131, title: 'Title 18'}, {id: 55, title: 'Title 234'} ]; // 找到id为131的元素 const requiredIndex = posts.map(p => p.id).indexOf(131);
译者注:这里我以为方法很繁琐。可使用findIndex方法:
const requiredIndex = posts.findIndex(obj=>obj.id===131);
,一样能获取到下标值2。
有了这些强大的方法,我但愿你的代码会变得愈来愈稳定和一丝不苟。当你的团队中有一个新的开发者加入时,能够向他推荐这篇文章,让他了解之前不知道的秘密。
这个翻译项目才开始,之后会翻译愈来愈多的做品。我会努力坚持的。
项目地址: https://github.com/WhiteYin/translation