in reply to Re: Convert a string into a hash
in thread Convert a string into a hash

I do need the corresponding values, because I'll sort a given list of tokens from this set. johngg got the idea!

This was the best I could do:

my %code = ( my $i = 0 or map { $_ => $i++ } split /,/, $tokens );

but I wanted to have no temporary variables... ;-)

Replies are listed 'Best First'.
Re^3: Convert a string into a hash
by ikegami (Patriarch) on Aug 15, 2009 at 02:18 UTC
    Conditional my isn't allowed. Besides, your code doesn't compile. You want
    my %code = do { my $i = 0; map { $_ => $i++ } split /,/, $tokens };

    If you really want no explicitely declared temp variables, you can use the following:

    my %code = sub { map { $_[$_] => $_ } 0..$#_ }->( split /,/, $tokens ) +;

    But honestly, there's no need to limit the scope that badly. Either of the following are quite suitable:

    my $i = 0; my %code = map { $_ => $i++ } split /,/, $tokens;
    my @code = split /,/, $tokens; my %code = map { $code[$_] => $_ } 0..$#code;

      Conditional my isn't allowed. Besides, your code doesn't compile.

      Yes, it does... without use strict; !!!

      Thanks for point that out.

        Fine, it compiles without strict but it has two additional errors.
        • It's not using strict :)

        • Package var $i is used when you intended lexical $i to be used. Why bother declaring lexical $i if you're not going to use it and you're ok with using the (unlocalised!!!) package var? Your code is equivalent to

          my %code = map { $_ => $i++ } split /,/, $tokens; my $i = 0

          so you should use the following is you think it's fine

          my %code = map { $_ => $i++ } split /,/, $tokens;
Re^3: Convert a string into a hash
by Your Mother (Archbishop) on Aug 14, 2009 at 23:20 UTC

    I can see how you can do that but not why you'd want to do it. The array is sorted already. There is no information in a hash with index values that isn't in an array. So, unless I'm missing something, it buys you nothing except a speed penalty and obfuscates a simple operation/need. If you could explain what you're going to do with it in the end, you might get some more interesting answers approaches. :)

      There is no information in a hash with index values that isn't in an array.

      Yes and no. If you want to know "the position of a given number", the information is there in the array, but finding it is hard (O(N)). It's O(1) with a hash.

      my ($index) = grep $code[$_] == $x, 0..$#code; -vs- my $index = $code{$x};

        NIce comparison/example of a possible why. With List::Util::first, or equivalent code, you could at least move the array more to the middle ground (on average); I know you know that already and it's good (for me at least) to be confronted with the algorithm costs. That alone suggests a reason for doing it with the hash.

      I'm sorry for not being so clear. English is not my native language, so I decided just to write the code in the usual way with a minimum of info about the context. I thought this thread as a perl coding hackers topic.

      BTW, my best code really was:

      my %code = (my $i = 0 or map {($_, $i++)} split(/,/, $tokens));

      The previous was an updated one using => instead of the subarray, a more elegant code based on your reply, but I didn't notice my mistake when I pasted the line.

        vitoco:

        Yes, it's a perl coding hackers topic. But what Your Mother was trying to convey is that you might be focused too tightly on the details. Sure, we can help you get an answer to your question....but you might be asking the wrong question.

        Example: Suppose you're walking through the woods trying to get to Grandmother's house. The path branches several times here and there, and you're worried about getting lost. So you're walking along the path, and you find a ravine in your path, and the rope bridge across it is broken. So now you're trying to cross the ravine. You successfully make rope by weaving together tree bark, and you're trying to build a new rope bridge. But you're having trouble trying to lasso a stump on the other side of the ravine. So you use your magic whistle to call a helpful mystical owl from the sky and ask it "How can I lasso the stump over there?".

        The owl will happily try to help you construct your rope bridge. But if you happened to phrase your question as "Hi, I'm trying to get to Grandmother's house, but this ravine is in my way. I'm trying to figure out how to cross it. Now I've made this rope, and I think all I need to do is lasso that stump so I can cross this ravine. Can you help?" Then the owl could offer, "Well, I can help you cross the ravine. But if you're trying to get to Grandmother's house, it would be much simpler to go back two intersections and take a left, take your next right at the large rock, and it's about 100 yards further."

        In other words, by focusing in on the smaller problems (as we programmers are often wont to do), you may have created an artificial problem for yourself to solve, when simpler and more direct solutions are available. If don't give us enough information, we'll try to help you cross the ravine, but if you give us some context of what you're trying to accomplish, we might be able to direct you to the already created Grandmother::House module or some such.

        ...roboticus

        in a somewhat whimsical mood.