how to sory array data using NATURAL programming

hi i have a doubt
my map is an array as mentioned below
1 #MAP-DETAILS
2 #MAP-DOCUMENT-ID (A10/1:12)
2 #MAP-OPEN-DATE-CYMD (A08/1:12)
2 #MAP-UPDATE-DATE-CYMD (A08/1:12)
2 #MAP-FOLLOW-UP-DATE-CYMD (A08/1:12)
2 #MAP-RESPONSIBLE-REGION (A02/1:12)
2 #MAP-RESPONSIBLE-DISTRICT (A03/1:12)
2 #MAP-SERVICING-DEALER-NUMBER (A07/1:12)
2 #MAP-SERVICING-DEALER-NAME (A11/1:12)

i want to sort this array by
#MAP-SERVICING-DEALER-NAME

actually these map array variables are stored value from file which satisfies certain conditions.

i want to sort the only the value present in this array

please any one help

Education, Education, Education.
You will never learn Natural just “playing” with the language.

Here is a program which demonstrates how to SORT an array. Note that the subscript is included in the sort.

  • This program demonstrates the fallacy of a common misconception
  • regarding SORT, namely that it can only be used to SORT records.
  • SORT is equally effective at SORTing an array.
  • Yes, I know we could have had SORT in the READ loop. We will
  • assume, however, that there was actually some processing going
  • on in the READ loop in addition to the initializing of our
  • array of names.

DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 NAME
1 #NAME (A20/1:10)
1 #LOOP (P3) INIT <1>
1 #NAME-HOLD (A20)
END-DEFINE
*
INCLUDE AATITLER
INCLUDE AASETC
*
READ (10) MYVIEW
MOVE NAME TO #NAME (#LOOP)
ADD 1 TO #LOOP
END-READ
*
FOR #LOOP = 1 TO 10
MOVE #NAME (#LOOP) TO #NAME-HOLD
DISPLAY #LOOP #NAME-HOLD
END-ALL
SORT BY #NAME-HOLD USING #LOOP
AT START OF DATA NEWPAGE END-START
DISPLAY #LOOP #NAME-HOLD
END-SORT
END

====================== OUTPUT =========================
PAGE # 1 DATE: 24-Jul-2008
PROGRAM: SORT06 LIBRARY: SNDEMO

#LOOP #NAME-HOLD


1 VERDIE
2 GUERIN
3 VAUZELLE
4 CHAPUIS
5 MONTASSIER
6 JOUSSELIN
7 BAILLET
8 MARX
9 D’AGOSTINO
10 LEROUGE

PAGE #   2                    DATE:    24-Jul-2008
PROGRAM: SORT06               LIBRARY: SNDEMO

#LOOP #NAME-HOLD


7 BAILLET
4 CHAPUIS
9 D’AGOSTINO
2 GUERIN
6 JOUSSELIN
10 LEROUGE
8 MARX
5 MONTASSIER
3 VAUZELLE
1 VERDIE

Note the subscripts. In your case you would do something like:

FOR #LOOP = 1 TO 12
MOVE #MAP-SERVICING-DEALER-NAME TO #NAME
END-ALL
SORT BY #NAME USING #LOOP
DISPLAY #NAME #LOOP #MAP-DOCUMENT-ID (#LOOP) #MAP-OPEN-DATE-CYMD (#LOOP) etc.

steve

along with this i want to implement page-up and page-down concept…Can you please help me

thankyou…sorting worked fine…but i have 1 more problem…how will i display to this sorted array in the online screen

Nishadas wrote:

thankyou…sorting worked fine…but i have 1 more problem…how will i display to this sorted array in the online screen

Have your management send you to an introductory Natural class where you will learn about Maps, the Map Editor, WRITE, DISPLAY, INPUT, etc.

steve

no…i didnt have any such sessions…k anyways thakyou very much…anyways i could do it…actually i wanted to sort array then move this to may which is also array…using sort verb i was not able to do it…so i used the sort method which we used to do in c

no…i didnt have any such sessions…k anyways thakyou very much foe ur help:lol:…anyways i could do it…actually i wanted to sort array then move this to may which is also array…using sort verb i was not able to do it…so i used the sort method which we used to do in c …thank you very much…:

Warning: This is not a howto post, but very wishful thinking:

Actually I have always wondered why Natural has such a lousy SORT implementation. Why do you have to do an END-ALL and destroy all open loops? Why do you have to do so much coding to have an array sorted? I have repeatedly brought up ideas on the user conferences how to do this more elegant, but Software AG seem not interested in offering a user friendly sort statement.

At our company we created an assembler module back in the mid 1980s to do the sorting. We also use it for page control in multi page applications. And we still use it today, over 20 years later.

My idea for how it SHOULD work is to define a group array like nishadas did, but maybe as a multiple group:
DEFINE DATA LOCAL
1 #SORT-GROUP (1:n)
2 #SORT-KEY1 (A10)
2 #SORT-KEY2 (A20)
2 #SORT-FIELD1 (N5)
2 #SORT-FIELD2 (L)
2 …
DEFINE DATA

After having populated the array the sorting should be done in a snap by Natural, like this:
SORT #SORT-GROUP BY #SORT-KEY1 #SORT-KEY2

Voila, now you should have been able to read the array. Of cause it should be possible to refer to any field from the array as sort keys, regardless of their names.

This was and still is my wishful thinking. Sorry it did not bring you a good solution, but this is a proper opportunity for me to bring it up once again.

have a look at http://scctoolkit.atspace.com and look at QSORT. This is generic array sort using quicksort.

Note Henrik that Steve’s solution is really quite quick and simple to code.
I agree that your idea is very nice but it is perhaps not worth the cost?
In fact, in Steve’s solution you do not need to even move the array field. You can just return a sorted list of the index.
For example:

1 #I (I2)
1 #S (I2)
1 #ARRAY (…)
2 #DATA-A
2 #DATA-B

FOR #I = 1 TO …
#S := #I
END-ALL
SORT BY #DATA-B(#S) USING #S
DISPLAY #ARRAY(#S)
END-SORT

NO !!! Do NOT do this.

Where to start. Many years ago I discovered what I thought was an anomaly within the SORT syntax. The documentation says that operand1, which is(are) the argument(s) of the BY clause can only be “S”, which stands for “Simple Variable”. Nonetheless, I had many examples where I had things like BY ARRAY (1) and even BY ARRAY (1) ARRAY (2). Note that BY ARRAY (1:2), which one would expect should also work (merely an abbreviation for BY ARRAY (1) ARRAY (2)) does not compile.

In all cases, however, I worked with “fixed” members of the array.

So, I was a bit surprised to see your code where you were sorting by a variable member of the array.

At first, I basically copied your program. It “worked”, or at least it seemed to work. The more I thought about it, I could not imagine what Natural was doing behind the scenes. In particular, I could not figure out how the sorted data got into the “proper” place within the array.

I added some code to the original program, and modified the code as you showed above:

  • This program demonstrates the fallacy of a common misconception
  • regarding SORT, namely that it can only be used to SORT records.
  • SORT is equally effective at SORTing an array.
  • Yes, I know we could have had SORT in the READ loop. We will
  • assume, however, that there was actually some processing going
  • on in the READ loop in addition to the initializing of our
  • array of names.

DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 NAME
1 #NAME (A20/1:10)
1 #LOOP (P3) INIT <1>
1 #NAME-HOLD (A20)
1 #s (i2) init <10>
END-DEFINE
*
INCLUDE AATITLER
include aasetc
*
READ (10) MYVIEW
MOVE NAME TO #NAME (#LOOP)
display #name (#loop) #loop
ADD 1 TO #LOOP
END-READ
*
FOR #LOOP = 1 TO 10
#S := #loop

END-ALL
SORT BY #NAME (#S) USING #s
AT START OF DATA NEWPAGE END-START
DISPLAY #name (#S) #S
END-SORT
newpage
for #loop = 1 to 10
write #name (#loop) #loop
end-for
END

PAGE #   1                    DATE:    09-09-17
PROGRAM: SORT06               LIBRARY: INSIDE

   #NAME         #LOOP

ADAM 1
MORENO 2
BLOND 3
MAIZIERE 4
CAOUDAL 5
VERDIE 6
GUERIN 7
VAUZELLE 8
CHAPUIS 9
MONTASSIER 10

PAGE #   2                    DATE:    09-09-17
PROGRAM: SORT06               LIBRARY: INSIDE

   #NAME         #LOOP

ADAM 1
BLOND 3
CAOUDAL 5
CHAPUIS 9
GUERIN 7
MAIZIERE 4
ADAM 10
MORENO 2
VAUZELLE 8
VERDIE 6

PAGE #   3                    DATE:    09-09-17
PROGRAM: SORT06               LIBRARY: INSIDE

   #NAME         #LOOP

BLOND 1
VAUZELLE 2
CAOUDAL 3
MONTASSIER 4
CHAPUIS 5
VERDIE 6
MAIZIERE 7
VERDIE 8
GUERIN 9
MORENO 10

Pages one and two above looked promising. They were the same output as my original code. HOWEVER, look at page 3. Whoops. This is not the same as Page two output, which is what we would want.

Okay, do NOT do this, unless, all you want is to see the sorted data. Clearly the original array no longer exists for further processing.

I will play with this a bit more. Could probably figure out what type of sort is being used by the final arrangement of the array elements.

steve

This is interesting, thank you. I have been under the impression that a single instance of an array element can be used wherever a simple variable is expected. It has always worked. Am I programming on thin ice?

Note by the way that the code is not moving the data in the array, it is like your example in the first answer to nishadas, just returning a sorted list of the index #LOOP. If you were to add the FOR #LOOP = 1 TO 10 final loop to your first example that’d also get the same result. The only difference between our examples is between using a copy of the sort key value versus a copy of the index (not affected by the FOR incrementation).

What I like about using a copy of the index rather than the key value is that when you have multiple and/or very long sort keys you are still only moving two bytes around in the sort USING, rather than the entire key length, plus there is no need for coding all the extra local key variables and moving the key values to them.

PS. Please excuse that last paragraph - I got confused between the advantage of USING the index rather than array data, and the advantage of BY array sort keys than than copies of the array sort key.
Of course the key values are always passed around in the sort!

What I should have said was:

What I like about using a copy of the index rather than the key value is that when you have multiple and/or very long sort keys there is no need for coding all the extra local key variables and moving the key values to them.

Hi Anthony;

“Note by the way that the code is not moving the data in the array,”

True, but the SORT is changing the array.

Take a look at Page 1 and Page 3 of output. They are both displaying #NAME (1:10), before and after the SORT. The names are not in the same order. There are even duplicates in the page 3 list.

What I missed the first time around was noting that even page 2 output was incorrect; look at the duplicate of ADAM.

Here is the problem with having the subscripted array in the SORT.

Suppose I have the following code:

READ (10) MYVIEW
:::
END-ALL
SORT BY NAME USING CITY COUNTRY
DISPLAY NAME CITY COUNTRY
END-SORT

Natural reads a record from Adabas; processes the record, then creates a “spin-off” record to be used by the sort. After processing all ten records, the spin off file looks like:

               NAME-1   CITY-1    COUNTRY-1
               NAME-2   CITY-2    COUNTRY-1
                :::::::::::::::::::::::::::::::::
               NAME-10 CITY-10   COUNTRY-10

Natural now sorts the spinoff file. Now takes the first spinoff record and places it in the memory locations MYVIEW.NAME MYVIEW.CITY MYVIEW.COUNTRY. etc.

The point is that the values from the spinoff record are being placed in memory locations.

Okay, on to the code that doesn’t quite do what one expects:

SORT BY #NAME (#S) USING #S

the spinoff part is easy. The spinoff file correctly has values 1…10 for #S and the appropriate names from #NAMES.

Now the fun part. After the sort, Natural takes the first entry in the spinoff file, which would be ADAM 1, and puts the 1 in #S and puts ADAM … WHERE ??? Note the “problem” is that we are indeed putting values into the array.

Suppose (and I have not confirmed this yet), Natural looks at #NAME (#S) before moving the 1 into #S. What is in #S? Answer, probably 10 from the first loop. Hence ADAM goes into #NAME (10).

Okay, the second entry in the spinoff file is BLOND - 2. Where does Natural put BLOND? The value of #S is 1 (from the move of the first spinoff record). Hence, BLOND appears in #NAME (1). If you look at Page 3 of the output, this is indeed true.

I have to leave in a few minutes. When I get back I will continue “playing” SORT, to try and confirm what is going on.

Regardless of the “behind the scenes” stuff, it should be clear that the array has been destroyed by the basic SORT actions.

More this afternoon. Have a good weekend playing with this. javascript:emoticon(‘:D’)

steve

The one problem that I have run into using the Natural SORT statement is the limitation of having only one active sort. When the sort needs to be done in a subprogram that may be called by many processes, and those processes have their own sort, you get a Natural error.

For these situations we have a sort subprogram that takes in an array (A80/1:V). (It was written long ago, today it could easily be (A/1:*).) The calling program defines it’s own array and redefines it as needed, moves the data into the array and calls the sort.

Oh wow… I have been VERY lucky on that thin ice! Thank you very much Steve!

Hi Jerome;

While Natural still does not allow multiple active SORT loops, other restrictions have been eliminated. For example, you can now have multiple SORT loops in one program (both inside subroutines and in the main line).

Very often people employed external subroutines/subprograms to avoid the restriction of one SORT per object. Your code might be able to exist in one object today.

steve

Hi Anthony;

If you have production code like you posted, you have been very lucky,… that no one noticed the problem.

This code always destroys the array, and, even if you just use the values in the SORT loop, always has a duplicate entry where the last array member should be.

I will be writing an article on this for Inside Natural’s next (November) issue. I will also post the article here.

steve

Hi Anthony;

This may look like strange code, but it does establish the correct data for the second page. WARNING, the array will still be incorrect, look at the output for page three.

The start of the program is the same as shown in earlier post (SORT06). Then, starting with the FOR loop, here is the modified code. There may be an easier way to achieve this, but I have not found it yet. Also, it involves minimal change to the original code, which might be of concern to you.

FOR #LOOP = 1 TO 11
if #loop ne 11
#S := #loop
else
#S := 1
escape bottom
end-if
END-ALL
SORT BY #NAME (#S) USING #s
AT START OF DATA NEWPAGE END-START
DISPLAY #name (#S) #S
END-SORT
newpage
for #loop = 1 to 10
write #name (#loop) #loop
end-for
END

PAGE #   1                    DATE:    09-09-19
PROGRAM: SORT06F              LIBRARY: INSIDE

   #NAME         #LOOP

ADAM 1
MORENO 2
BLOND 3
MAIZIERE 4
CAOUDAL 5
VERDIE 6
GUERIN 7
VAUZELLE 8
CHAPUIS 9
MONTASSIER 10

PAGE #   2                    DATE:    09-09-19
PROGRAM: SORT06F              LIBRARY: INSIDE

   #NAME         #LOOP

ADAM 1
BLOND 3
CAOUDAL 5
CHAPUIS 9
GUERIN 7
MAIZIERE 4
MONTASSIER 10
MORENO 2
VAUZELLE 8
VERDIE 6

PAGE #   3                    DATE:    09-09-19
PROGRAM: SORT06F              LIBRARY: INSIDE

   #NAME         #LOOP

BLOND 1
VAUZELLE 2
CAOUDAL 3
MONTASSIER 4
CHAPUIS 5
VERDIE 6
MAIZIERE 7
VERDIE 8
GUERIN 9
MORENO 10

steve