Skip to main content
September 15, 2010
Question

chronological order number needs in index numbers to be changed as ndash

  • September 15, 2010
  • 2 replies
  • 12329 views
Hi all


I have a task to complete the below requirement for Index part in a book. Please help me.


I have sequence of numbers like this,


Index1, 26, 35, 36, 37, 47
Index2, 65, 78, 79, 89, 90


I need to change like this

Index1, 26, 35−37, 47
Index2, 65, 78−79, 89−90


i.e., the number which are in sequence order (chronological order) needs to be changed as ndash.

Sajeev

This topic has been closed for replies.

2 replies

Marc Autret
Legend
September 15, 2010

Hi all,

Here is the routine I use in IndexMatic 2 (script-in-progress). That's certainly equivalent to Bob's and/or Peter's approach, but why not sharing:

function makeSequences(/*Number[]*/numbers, /*String*/separator, /*String*/linker)
{
separator = separator || ", ";
linker = linker || "-";

if( numbers.length < 2 ) return numbers.join('');

var a = numbers.concat().sort(function(x,y){return x-y;}),
     sz = a.length-1, i = 0, i0 = 0, n = a[0], r = [];

var format = function()
     {
     r.push(a[i0] + ((i-i0)>1 ? linker+a[i-1] : ''));
     return i0=i;
     };

while( i<sz && ( n+1>=(n=a[++i]) || format()));
format();
return r.join(separator);
}


// Sample code:

var myTest1 = [ 1, 2, 4, 6, 9, 10, 11, 12, 13, 14, 15, 18, 19, 30 ];
alert( makeSequences(myTest1, ", ", "\u2013") );
// => 1–2, 4, 6, 9–15, 18–19, 30

var myTest2 = [ 5, 3, 4, 4, 6, 6, 9, 12, 1, 18, 21, 22, 22, 0, 8 ];
alert( makeSequences(myTest2, " | " ) );
// => 0-1 | 3-6 | 8-9 | 12 | 18 | 21-22

@+

Marc

Harbs.
Legend
September 15, 2010

Since we're all sharing, here's the function I wrote about two and a half years ago. (If I were writing it now, it would probably look a lot nicer...)


function FixIndexRanges(){
    var story = app.selection[0].parentStory;
    var storyWords = story.words;
    for(var i=storyWords.length-1;i>0;i--){
        var curNumber = parseFloat(storyWords.contents);
        var prevNumber = parseFloat(storyWords[i-1].contents);
        if(curNumber!=NaN && prevNumber!=NaN && prevNumber==curNumber-1){
            var insertNumber = curNumber+0;
            var theIndex = storyWords.characters[0].index-1;
            while(prevNumber==insertNumber-1){
                i--;
                insertNumber--;
                try{
                    var prevNumber = parseFloat(storyWords[i-1].contents);
                    }catch(e){break}
                }
            var theIPIndex = storyWords.insertionPoints[0].index;
            story.texts.itemByRange(storyWords.characters[0],story.characters.item(theIndex)).remove();
            story.insertionPoints[theIPIndex].contents=insertNumber+'-';
            }
        }
    }

Harbs

September 16, 2010

cool script  Harbs

really nice one

Sajeev

Bob Stucky
Adobe Employee
Adobe Employee
September 15, 2010

Thanks for the fun morning algorithm exercise...

I think this will do it for you.

Regards

Bob

indexize = function( ar ) {
    var out = new Array();
    for ( var i = 0; i < ar.length; i++ ) {
        var a = i + 1;
        var current = ar[ i ];
        var concat = false;
        while ( parseInt( ar[ a++ ] )== ( current + 1 ) ) {
            current = ar[ a - 1 ];
            concat = true;
        }
        if ( concat ) {
            if ( parseInt( ar[ i ] ) + 1 == current ) {
                out.push( ar[ i ] );
                out.push( ar[ i + 1 ] );
            } else {
                out.push( ar[ i ] + "-" + current  );
            }
        } else {
            out.push( ar[ i ] );
        }
        i = a - 2;
    }
    return out;
}

var a = [ 1, 2, 4, 5, 7, 9, 11, 12, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26, 27, 30, 31, 33, 34, 35, 36, 40, 41, 43,44,45,47,48,50 ];
$.writeln( "Input: " + a );
debugger;
$.writeln( "Output: " + indexize( a ) );

Bob Stucky
Adobe Employee
Adobe Employee
September 15, 2010

Oh, and do you really want 65,78,89,90 to contain 89-90?

It doesn't make sense (to me) to have sequences of 2 digits have a hyphen.

But if you do, make the "if (concat)" block look something like:

out.push( concat ? ( ar[ i ] + "-" + current ) : ar[ i ] );

Bob

Community Expert
June 29, 2011

Very nice!

Is there a reason you'd want to use a tolerance of 0?

I like to make function interfaces as easy to use as possible.

This version makes the dash and tolerance optional:

function page_ranges (array, obj)
{
    obj = obj || {};
    var temp = [];
    var range = false;
    var tolerance = obj.tolerance || 0;
    var dash = obj.dash || "-";
    for (var i = 0; i < array.length; i++)
    {
        temp.push (array);
        while (array[i+1] - array <= tolerance)
            {i++; range = true}
        if (range){
            temp[temp.length-1] += dash + array;
        }
        range = false;
    }
    return temp;
} // page_ranges

Harbs


@Peter & Harbs:

I suppose the page_ranges function takes only arrays of well prepared numbers: sorted and single standing doubles eliminated when using tolerance 0.

See the following tests I did:

//TESTS:
var a = [1,1,10,10,11,11,11,11,11,14,15,16,222,222,223,289];

$.writeln("Tolerance: 0\t" + page_ranges (a, {tolerance: 0, dash: "-"}));
//Returns: 1-1,10-10,11-11,14,15,16,222-222,223,289

$.writeln("Tolerance: 1\t" + page_ranges (a, {tolerance: 1, dash: "-"}));
//Returns: 1-1,10-11,14-16,222-223,289

$.writeln("Tolerance: 3\t" + page_ranges (a, {tolerance: 3, dash: "-"}));
//Returns: 1-1,10-16,222-223,289

function page_ranges (array, obj)
{
    obj = obj || {};
    var temp = [];
    var range = false;
    var tolerance = obj.tolerance || 0;
    var dash = obj.dash || "-";
    for (var i = 0; i < array.length; i++)
    {
        temp.push (array);
        while (array[i+1] - array <= tolerance)
            {i++; range = true}
        if (range){
            temp[temp.length-1] += dash + array;
        }
        range = false;
    }
    return temp;
}

Seems array[0] should get a special treatment when it's contents is not part of a range and it is doubled…

Uwe