Idiomatic way to get array of possible slices from string

Discussion in 'Ruby' started by drKreso, Jan 4, 2012.

  1. drKreso

    drKreso Guest

    I am interesed in Ruby idiomatic way to get array of all possible
    slices of particular string. For example
    if I have string "hello" i would like to get

    ["hello", "ello", "llo", "lo", "o", "default"]

    and a "default" on the end... This is what I came up with but it
    doesn't feel right.

    # all possible keys
    # ex. for 211 keys are [211,11,1,"default"]
    def keys
    result = []
    amount_as_string = @amount.to_s
    while(amount_as_string != "")
    result << amount_as_string.to_i
    amount_as_string.slice!(0)
    end
    result << "default"
    end

    Help would be appreciated.

    Best Regards

    Kresimir Bojcic

    www.kresimirbojcic.com
     
    drKreso, Jan 4, 2012
    #1
    1. Advertising

  2. * drKreso <> (23:33) schrieb:

    > I am interesed in Ruby idiomatic way to get array of all possible
    > slices of particular string. For example
    > if I have string "hello" i would like to get
    >
    > ["hello", "ello", "llo", "lo", "o", "default"]


    Your example doesn't fit the specification. For example, "hell", "ell",
    "ll" are also splices of "hello", as well as all the single letters.

    > and a "default" on the end...


    Why is that?

    > This is what I came up with but it doesn't feel right.


    Above you do strings, here so deal only with the string representation
    of a number, and feed numbers in your result array.

    ># all possible keys
    > # ex. for 211 keys are [211,11,1,"default"]
    > def keys
    > result = []
    > amount_as_string = @amount.to_s
    > while(amount_as_string != "")
    > result << amount_as_string.to_i
    > amount_as_string.slice!(0)
    > end
    > result << "default"
    > end


    That would certainly return something like your example.

    To produce something like the specification says, I would try:

    def all_splices s
    len = s.length
    r = []
    (0..len-1).each do | i |
    (1..(len-i)).each do | l |
    r << s[i, l]
    end
    end
    r << "default"
    end

    Untested, so certainly wrong.

    mfg, simon .... l
     
    Simon Krahnke, Jan 5, 2012
    #2
    1. Advertising

  3. drKreso

    drKreso Guest

    Thanks. I am building an inflector for certain words. For example
    week. (In Croatian it is not so simple).
    So you have(week = tjedan):

    tjedan:
    default: tjedana
    1: tjedan
    2: tjedna
    3: tjedna
    4: tjedna
    11: tjedana
    12: tjedana
    13: tjedana
    14: tjedana

    Now if i have 21 for example i try to find 21 in my hash. If no direct
    hit is found I look for 1 and decide it is 21 tjedan.
    If I have 2014 I look for 2014 - nothing, then 014 - nothing, then 14
    and i decide it is 2014 tjedana.
    If I have 77 I look for 77 - nothing, then I look for 7 - nothing, and
    I decide it is 77 tjedana (default).
    So I don't need all the slices, just the one in the example and then I
    use that array to do "match"


    # first non nil match wins, there is guaranteed to be at least one
    (default)
    def inflected
    keys.map { |key| @unit_inflections[key] }.compact[0]
    end

    Still I suspect there is more elegant way that to use while

    On Jan 5, 4:44 am, Simon Krahnke <> wrote:
    > * drKreso <> (23:33) schrieb:
    >
    > > I am interesed in Ruby idiomatic way to get array of all possible
    > > slices of particular string. For example
    > > if I have string "hello" i would like to get

    >
    > > ["hello", "ello", "llo", "lo", "o", "default"]

    >
    > Your example doesn't fit the specification. For example, "hell", "ell",
    > "ll" are also splices of "hello", as well as all the single letters.
    >
    > > and a "default" on the end...

    >
    > Why is that?
    >
    > > This is what I came up with but it doesn't feel right.

    >
    > Above you do strings, here so deal only with the string representation
    > of a number, and feed numbers in your result array.
    >
    > ># all possible keys
    > >  # ex. for 211 keys are [211,11,1,"default"]
    > >  def keys
    > >    result = []
    > >    amount_as_string = @amount.to_s
    > >    while(amount_as_string != "")
    > >      result << amount_as_string.to_i
    > >      amount_as_string.slice!(0)
    > >    end
    > >    result << "default"
    > >  end

    >
    > That would certainly return something like your example.
    >
    > To produce something like the specification says, I would try:
    >
    > def all_splices s
    >   len = s.length
    >   r = []
    >   (0..len-1).each do | i |
    >     (1..(len-i)).each do | l |
    >       r << s[i, l]
    >     end
    >   end
    >   r << "default"
    > end
    >
    > Untested, so certainly wrong.
    >
    > mfg,                   simon .... l
     
    drKreso, Jan 5, 2012
    #3
  4. drKreso

    drKreso Guest

    After playing with each_cons (that seemed promising but I was unable
    to put it together) I've noticed good old take.
    So I've ended up with this:

    # all possible keys
    # ex. for 211 keys are [211,11,1,"default"]
    def keys
    (1..amount_as_array.size).inject(["default"]) { |result,n| result
    << amount_as_array.take(n).join.reverse.to_i }.reverse
    end

    def amount_as_array
    @amount.to_s.split(//).reverse
    end

    This seems much more idiomatic, not to mention while is almost a code
    smell :)

    Kresimir Bojcic

    www.kresimirbojcic.com
     
    drKreso, Jan 5, 2012
    #4
  5. On 01/05/2012 09:42 AM, drKreso wrote:
    > After playing with each_cons (that seemed promising but I was unable
    > to put it together) I've noticed good old take.
    > So I've ended up with this:
    >
    > # all possible keys
    > # ex. for 211 keys are [211,11,1,"default"]
    > def keys
    > (1..amount_as_array.size).inject(["default"]) { |result,n| result
    > << amount_as_array.take(n).join.reverse.to_i }.reverse
    > end
    >
    > def amount_as_array
    > @amount.to_s.split(//).reverse
    > end
    >
    > This seems much more idiomatic, not to mention while is almost a code
    > smell :)


    If I understand your requirement properly, all you need is the trailing
    number of digits. That could be obtained in a different way:

    def keys(i)
    if block_given?
    i.to_s.length.downto 1 do |n|
    yield i % 10**n
    end
    else
    to_enum:)keys, i)
    end
    end

    irb(main):021:0> keys(123) {|x| p x}
    123
    23
    3
    => 3
    irb(main):022:0> keys(123).to_a
    => [123, 23, 3]

    Kind regards

    robert
     
    Robert Klemme, Jan 5, 2012
    #5
  6. drKreso

    drKreso Guest

    Great,

    Yes I need trailing number of digits. Great idea with %

    I've settled for this:

    def trailing_digits
    (amount_length.downto 1).map { |n| @amount % 10**n } << "default"
    end

    Thanks,

    Best Regards,

    Kresimir Bojcic
    htttp://www.kresimirbojcic.com


    On Jan 5, 10:46 am, Robert Klemme <> wrote:
    > On 01/05/2012 09:42 AM, drKreso wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > After playing with each_cons (that seemed promising but I was unable
    > > to put it together) I've noticed good old take.
    > > So I've ended up with this:

    >
    > >    # all possible keys
    > >    # ex. for 211 keys are [211,11,1,"default"]
    > >    def keys
    > >      (1..amount_as_array.size).inject(["default"]) { |result,n| result
    > > <<  amount_as_array.take(n).join.reverse.to_i }.reverse
    > >    end

    >
    > >    def amount_as_array
    > >      @amount.to_s.split(//).reverse
    > >    end

    >
    > > This seems much more idiomatic, not to mention while is almost a code
    > > smell :)

    >
    > If I understand your requirement properly, all you need is the trailing
    > number of digits.  That could be obtained in a different way:
    >
    > def keys(i)
    >    if block_given?
    >      i.to_s.length.downto 1 do |n|
    >        yield i % 10**n
    >      end
    >    else
    >      to_enum:)keys, i)
    >    end
    > end
    >
    > irb(main):021:0> keys(123) {|x| p x}
    > 123
    > 23
    > 3
    > => 3
    > irb(main):022:0> keys(123).to_a
    > => [123, 23, 3]
    >
    > Kind regards
    >
    >         robert
     
    drKreso, Jan 5, 2012
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. proudfeet

    array slices

    proudfeet, Oct 1, 2003, in forum: VHDL
    Replies:
    1
    Views:
    638
    Egbert Molenkamp
    Oct 1, 2003
  2. Alex Polite

    No Array slices! What is this?

    Alex Polite, Jun 6, 2004, in forum: Java
    Replies:
    3
    Views:
    541
    John C. Bollinger
    Jun 7, 2004
  3. Replies:
    8
    Views:
    24,562
    Thomas G. Marshall
    May 30, 2005
  4. Patrick Tyler

    string/array slices

    Patrick Tyler, Mar 30, 2011, in forum: Ruby
    Replies:
    12
    Views:
    283
    Adam Prescott
    Mar 31, 2011
  5. Richard Harman
    Replies:
    8
    Views:
    198
    Anno Siegel
    Sep 24, 2005
Loading...

Share This Page