4 Replies - 569 Views - Last Post: 09 October 2013 - 06:27 AM Rate Topic: -----

#1 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1910
  • View blog
  • Posts: 3,954
  • Joined: 11-December 07

Chunk array -- code review request

Posted 09 October 2013 - 03:59 AM

If I have an array like this where "t" represents the ends of a chain:

arr = [1, 2, 3, "t", 4, 5, "t"]


My method should split it up like this:

[[1, 2, 3, "t"], [4, 5, "t"]]


The real problem:
Spoiler


Here is my method:

	def myChunk(arr)
		arr.reduce([[]]) do |acc, x|
			chunk = acc.last
			isNewChunk = (!chunk.empty?) && yield(chunk.last)
			if (isNewChunk)
				acc << [x]
			else
				chunk << x
				acc
			end
		end
	end


and a variation

	def myChunk(arr)
		arr.reduce([[]]) do |acc, x|
			chunk = acc.last
			isNewChunk = (!chunk.empty?) && yield(chunk.last)
			acc << (chunk = []) if isNewChunk
			chunk << x
			acc
		end
	end



Here it is in action:

irb(main):042:0> arr = [1, 2, 3, "t", 4, 5, "t"]
=> [1, 2, 3, "t", 4, 5, "t"]
irb(main):043:0> myChunk(arr){|x| x.eql?("t")}
=> [[1, 2, 3, "t"], [4, 5, "t"]]



I have 2 questions.

* I don't write much code in Ruby, so is there a better way to write this method? Maybe there a more concise way of determining isNewChunk, for example. Which of my two examples is better?

* Is there an existing method (or combination) in Ruby that will do this for me? Enumerable.chunk looks good but I'm using Ruby 1.8.7 at work which unfortunately doesn't have that method. take_while and drop_while looked promising but I don't think they can easily be made to do what I need.

This post has been edited by cfoley: 09 October 2013 - 04:05 AM


Is This A Good Question/Topic? 1
  • +

Replies To: Chunk array -- code review request

#2 xclite  Icon User is offline

  • LIKE A BOSS
  • member icon


Reputation: 877
  • View blog
  • Posts: 3,122
  • Joined: 12-May 09

Re: Chunk array -- code review request

Posted 09 October 2013 - 04:24 AM

From my digging around, chunk looks like as close as it gets.

Honestly, if you're in 1.8.7, I'd just do this the "unclever", but very clear way:
results = []
current = []
arr.each do |e|
  current << e
  if e == 't'
    results << current
    current = []
  end
end
return results


Was This Post Helpful? 2
  • +
  • -

#3 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1910
  • View blog
  • Posts: 3,954
  • Joined: 11-December 07

Re: Chunk array -- code review request

Posted 09 October 2013 - 04:33 AM

Thanks for your suggestion. It does look a lot clearer than mine. I forgot to mention that sometimes the last chain is missing a TER which would break your code. No reason I couldn't append one though.
Was This Post Helpful? 0
  • +
  • -

#4 xclite  Icon User is offline

  • LIKE A BOSS
  • member icon


Reputation: 877
  • View blog
  • Posts: 3,122
  • Joined: 12-May 09

Re: Chunk array -- code review request

Posted 09 October 2013 - 05:38 AM

Yeah I considered a case where it was missing but figured something like:
result << current unless current.empty?



Would be pretty simple if you didn't want to fudge the extra t on the string.
Was This Post Helpful? 1
  • +
  • -

#5 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1910
  • View blog
  • Posts: 3,954
  • Joined: 11-December 07

Re: Chunk array -- code review request

Posted 09 October 2013 - 06:27 AM

I hadn't picked up on that "unless" syntax before. Thanks for showing me it!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1