As you've discovered, it's easier to create a range based on integers than hex strings. But it's also easy to convert your strings of hex digits into numbers. They need literally as hex digits, which can be stored internally as integers.

Once your strings of hex digits are converted to integers, it becomes easy to use Number::Range to detect the ranges. (I'm using a portion of the __DATA__ segment from your Tk/Unicode post as a data set.)

use strict; use warnings; use Number::Rangify qw/rangify/; use v5.12; while( <DATA> ) { say "@{[$_->Size]}" for rangify( map hex, split ); } __DATA__ 00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB +00BC 00BD 00BE 00BF 00D7 00E6 00E7 00F0 00F7 00F8 0127 0131 014B 0153 0192 +019B 01C0 01C1 01C2 01C3 0237 0238 0239 023C 0240 0250 0251 0252 0253 0254 +0255

You can use the above snippet to convert your giant list of hex fields into smaller list containing one range per row (as base ten integers), in the format of:

160 191 215 215 230 231 240 240 247 248 295 295 305 305 331 331

With shell redirection you can dump it to a file, and use that as the starting point for the __DATA__ segment of your new script. That will reduce your __DATA__ segment from 5000+ individual string representations of hex down to about 120+ base ten integer ranges.

If you need to expand it again, you can do that easily enough as follows. This is NSFW, as I'll explain below:

use v5.12; use strict; use warnings; my @cp_ints = map{ eval join '..', split } <DATA>; my @cp_hexes = map sprintf( "%#x", $_ ), @cp_ints; __DATA__ 160 191 215 215 230 231 240 240 247 248 295 295 305 305

Notice that I took a short by using eval EXPR, which is only safe if you're in control of your input DATA.

I used eval to build ranges without explicitly splitting into variables that could sit on either side of a real range operator. In other words, I could have eliminated the eval with a more conventional construct like this:

while( <DATA> ) { my ( $low, $high ) = split; push @cp_ints, $low .. $high; }

But I was in a "play with eval" mood. The latter form is better for a number of reasons, but why not have fun while we're playing?

Anyway, with the two snippets you can take your original list of 5000+ items, reduce it to about 123 ranges, and then later reconstitute it back to your original 5000+ items.

Hope this helps.


Dave


In reply to Re: Crazy Golf : creating hex ranges from non-consecutive hex data values by davido
in thread Crazy Golf : creating hex ranges from non-consecutive hex data values by zentara

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.