- 浏览: 259074 次
- 性别:
- 来自: 苏州
-
文章分类
最新评论
-
px_dn:
谢谢!!
ubuntu server替换更新源 -
clark1231:
boiaprogramfan0420 写道求教一个问题 oc ...
像hackers一样写博客(三):幫你的Octopress增加文章分類 -
boiaprogramfan0420:
求教一个问题 octopress的read on功能怎么实现 ...
像hackers一样写博客(三):幫你的Octopress增加文章分類 -
leorn:
帮我解决问题了,谢谢
rails post方式提交表单,session丢失的解决办法 -
clark1231:
微博分享那个功能,我就给了个看到的链接,那个又不是我写的。我写 ...
像hackers一样写博客(二):Octopress设置与增加微博的侧边栏
Looping in Ruby seems to be a process of evolution for newcomers to the language. Newcomers will always find their way to the for loop almost immediately and when confronted with iterating an array, the first choice will generally be a for..in:
1 2 3 4 |
a = [1,2,3,4] for n in a puts n end |
This works, but its not very… Ruby. The next stage of evolution will be using an iterator for the first time. So the for loop gets dropped all together and each is used. The Rubyist is born at this point:
1 2 3 |
a.each do |n| puts n end |
What I see next is a lot of conditional logic being used inside the each block. The logic is generally introduced to perform the following operations:
- Building a list of items from an array.
- Total the items in an array.
- Find an item in the array.
So if this is you, then stop. Ruby has plenty more iterators where each came from. Which one you should be using depends on what operation you are trying to perform. So let’s take a look at our previous list and see if we can find a more Ruby way to get them done.
Building a list of items from the array using select
For this operation you should be using select. The way select works is simple, it basically iterates through all the elements in your array and performs your logic on each one. If the logic returns TRUE, then it adds the item to a new array which it returns when the iteration is complete. Here’s an example:
1 2 |
a = [1,2,3,4] a.select {|n| n > 2} |
This will return the last two elements in the array: 3 and 4. Why? Because 3 and 4 are both greater than 2, which was the logic we placed in the block. It’s worth noting that select has an evil step sister named reject. This will perform the opposite operation of select. Logic which returns FALSE adds the item to the array that is returned. Here’s the same examples as before except we will swap select, with reject:
1 2 |
a = [1,2,3,4] a.reject {|n| n > 2} |
In this example the return value is [1,2] because these elements return false when the condition is tested.
I also have to mention another close sibling to select and reject; collect, which returns an array of values that are the RESULT of logic in the block. Previously we returned the item based on the result of the CONDITION in the block. So perhaps we need square the values in our array:
1 2 |
a = [1,2,3,4] a.collect {|n| n*n} |
This returns a new array with each item in our array squared.
Finally, note that using select, reject, and collect returns an array. If you want to return something different, because you are concatenating or totaling values, then check out inject.
Total the items in an array using inject
When you think of accumulating, concatenating, or totaling values in an array, then think of inject. The main difference between select and inject is that inject gives you another variable for use in the block. This variable, referred to as the accumulator, is used to store the running total or concatenation of each iteration. The value added to the accumulator is the result of the logic you place in the block. At the end of each iteration, whatever that value is, can be added to the accumulator. For example, let’s sum all the numbers together in our array:
1 2 |
a = [1,2,3,4] a.inject {|acc,n| acc + n} |
This will return 10. The total value of all the elements in our array. The logic in our block is simple: add the current element to the accumulator. Remember, you must dosomething to the accumulator in each iteration. If we had simply placed n in the block the final value of the accumulator would have been 4. Why? Because its the last value in the array and since we did not add it to the accumulator explicitly the accumulator would be replaced in each iteration.
You can also use a parameter with the inject call to determine what the default value for the accumulator is:
1 2 |
a = [1,2,3,4] a.inject(10) {|acc,n| acc + n} |
In this example the result is 20 because we assigned the accumulator an initial value of 10.
If you need to return a string or an array from inject, then you will need to treat the accumulator variable that way. You can use the default value parameter of inject to do this:
1 2 |
a = [1,2,3,4] a.inject([]) {|acc,n| acc << n+n} |
In this example I add n to itself and then append it to the accumulator variable. I initialized the accumulator as an empty array using the default value parameter.
Find an item in the array using detect
Our last example operation was to find an element in the array. Let’s just put it out there and say that other iterators could be used to select the correct value from the array, but I am going to show you how to use detect to round out our exploration of these iterators.
So let’s find the value 3 in our array using detect:
1 2 |
a = [1,2,3,4] a.detect {|n| n == 3} |
This returns 3. The value we were looking for. If the value had not been found, then the iterator returns nil.
So if your head is spinning at this point as to which iterator to use for when, then remember this:
- Use select or reject if you need to select or reject items based on a condition.
- Use collect if you need to build an array of the results from logic in the block.
- Use inject if you need to accumulate, total, or concatenate array values together.
- Use detect if you need to find an item in an array.
By using these iterators you will be one step closer to mastering… Ruby-Fu.
发表评论
-
Ruby Require vs Load vs Include vs Extend
2013-02-18 16:42 1174load load用来多次加 ... -
发送ip地址和指定文件到某邮箱
2012-12-03 15:39 1234#!/usr/bin/env ruby # # ARGV[ ... -
jruby1.6.7.2 integer can't round
2012-07-10 09:32 985在jruby-1.6.7.2中 integer无法取roun ... -
ruby中的逻辑运算符
2012-06-11 07:43 1575def current_user @current_us ... -
the difference between nil, true, false, blank and empty
2012-06-07 16:20 1110The Nil Expression It’s pretty ... -
浅谈Ruby on Rails中的include和extend
2012-04-23 21:47 1173从模块引入方法、变量,使得编程变得简单,扩展性愈 ... -
ruby和rails的编程风格
2012-04-21 09:31 1182Ruby 社区首推的代码编写风格 原文: https ... -
Float round bug in ruby?
2012-03-24 07:35 1214ruby-1.8.7 > 1.55.round(1 ... -
ruby字符串处理函数
2012-02-28 15:46 11821.返回字符串的长度str.length => i ... -
六种用ruby调用执行shell命令的方法
2012-01-12 10:47 1087原创作品,允许转载,转载时请务必以超链接形式标明文章 ... -
Rubygems 镜像 - 淘宝网
2012-01-11 12:21 1123由于国内网络原因(你懂的),导致 rubygem ... -
Ruby 中获取目录大小
2012-01-07 22:33 970当前 Chito 中统计目录大小完全是偷懒的方式: ... -
Rubygem 常用命令整理
2011-12-23 09:00 1891gem install gem-name # 安装g ... -
Ruby学习笔记-循环与选择结构
2011-12-16 09:30 1142一、循环结构1. for…in语句:Ruby提供的for ... -
带序号循环Hash
2011-12-16 09:19 1127hash.keys.each_with_index do ... -
ruby case表达式
2011-12-07 16:27 9665Ruby 中的 case 语句非常强大,首先我们来看一个 ... -
Ruby 之 Block, Proc, Lambda
2011-12-06 16:54 1194Block 不是对象,是Ruby的语言特性,近似于闭包(C ... -
rails 上载xls文件
2011-12-02 15:09 1646以下两种form都可以上载文件(http://guides. ... -
rails 文件下载功能
2011-12-01 14:09 2595controller: class DownCon ... -
count vs length vs size
2011-11-08 15:47 1140In Ruby, #length and #size a ...
相关推荐
_.reduce(list, iterator, memo, [context]) Aliases: inject, foldl Also known as inject and foldl, reduce boils down a list of values into a single value. _.reduceRight(list, iterator, memo, [context]) ...
`all`, `any`, `collect`, `detect`, `findAll`, `grep`, `include`, `inject`, `invoke`, `max`, `min`, `partition`, `pluck`, `reject`, `sortBy`, `toArray`, `zip`, `inspect`, `map`, `find`, `select`, `...
`, `collect`, `detect`, `each_with_index`, `entries`, `find`, `find_all`, `grep`, `include?`, `inject`, `map`, `max`, `member?`, `min`, `partition`, `reject`, `select`, `sort`, `sort_by`, `to_a`, `zip...
7. `findAll(iterator)/select`: 类似于`detect`,但返回所有使`iterator`返回`true`的元素组成的数组。 8. `grep(pattern, iterator)`: 返回匹配`pattern`的所有元素,如果提供`iterator`,则返回经过`iterator`...