Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

To remove duplicate values and return unique array

Posted on 2011-03-03
10
Medium Priority
?
2,264 Views
Last Modified: 2013-12-26
I am in search of a powerbuilder fuction which would accept an arry, remove duplicate values from array and return unique values of array

for example
is_dwm_data_colname[1] = 'sman_code'
is_dwm_data_colname[2] = 'area_code'
is_dwm_data_colname[3] = 'mfg_code'
is_dwm_data_colname[4] = 'area_code'
is_dwm_data_colname[5] = 'mfg_code'
is_dwm_data_colname[6] = 'sman_code'

the returned array should be
is_dwm_data_colname[1] = 'sman_code'
is_dwm_data_colname[2] = 'area_code'
is_dwm_data_colname[3] = 'mfg_code'


0
Comment
Question by:Mehram
  • 5
  • 3
  • 2
10 Comments
 
LVL 2

Accepted Solution

by:
lbushby earned 1200 total points
ID: 35030125
There's no built in function but you could achieve what you want by copying the array to a column in a datastore then sort+filtering it to hide duplicate values before copying the column back to the array.  Example below:

// copy the array to a datastore (assumes datastore has been assigned a dataobject
// that contains a string column called 'dwm_data_colname')
lds_dedupe.Object.dwm_data_colname.primary = is_dwm_data_colname[]

// apply a sort+filter that discards duplicates
lds_dedupe.SetSort('dwm_data_colname A')
lds_dedupe.Sort()
lds_dedupe.Setfilter('GetRow()=1 OR dwm_data_colname <> dwm_data_colname[-1]')
lds_dedupe.Filter()

// copy the deduped column from the datastore back to the array
is_dwm_data_colname[] = lds_dedupe.Object.dwm_data_colname.primary

// the array now only contains distinct values
0
 

Author Comment

by:Mehram
ID: 35033721
Hi lbushby

I understand.

GetRow()=1 OR dwm_data_colname <> dwm_data_colname[-1] is a magical expression. My object Is achieved, but, please allow me to ask
Is it possible to create an imaginary datastore?
If so what is the syntax/script?

Thanks for your help.
0
 

Author Comment

by:Mehram
ID: 35034299
My the term "imaginary" I mean dataobject->datastore to be created and destroyed at runtime
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 2

Assisted Solution

by:lbushby
lbushby earned 1200 total points
ID: 35035069
Datastores objects are created and destroyed using CREATE/DESTROY.  Creating a dataobject at runtime can be done in several different ways.  Assuming you are actually connected to a database then probably the easiest way is to use SyntaxFromSQL to create a dataobject based on a SELECT statement.  The exact syntax will depend on the database in question.  The example below will work with Sybase SQLAnywhere which provides a 'dummy' table:

// EXAMPLE

datastore      lds_datastore
string      ls_syntax
string      ls_errors

// create a datastore
lds_datastore = create datastore

// generate syntax for a single string column called dwm_data_colname
// assumes SQLCA is connected to a database
ls_syntax = SQLCA.SyntaxFromSQL("SELECT '' AS dwm_data_colname FROM dummy", "", ls_errors )

// use the syntax to create a new dataobject
lds_datastore.Create(ls_syntax,ls_errors)

// the datastore is now ready to use as per the previous example

// having finished with the datastore, destroy it
destroy lds_datastore
 
0
 
LVL 1

Assisted Solution

by:goodwinfam
goodwinfam earned 800 total points
ID: 35035900
Here is what I have used for awhile extracted from my util nvo...   Note that this is from an export, so copy and paste accordingly (the first line before the ";" is the function and arg definition - not part of the script..

-------------------

public function integer of_arrayunique (long al_sourcevalues[], ref long al_uniquevalues[]);int            li_pos,li_cnt,li_tcnt,li_cnt2
long            ll_empty[],ll_value,ll_sourcevalues[]
boolean      lb_skip


// Initialize Return Array
ll_sourcevalues = al_sourcevalues
al_uniquevalues = ll_empty

// Loop Through Array Values
li_tcnt = upperbound(ll_sourcevalues)
for li_cnt = 1 to li_tcnt

      // Remove NULL Values
      lb_skip = FALSE
      ll_value = ll_sourcevalues[li_cnt]
      if isnull(ll_value) then continue

      // Compare
      for li_cnt2 = 1 to li_pos
            if ll_value = al_uniquevalues[li_cnt2] then
                  lb_skip = TRUE
                  continue
            end if
      next
      if lb_skip then continue

      // Include
      li_pos ++
      al_uniquevalues[li_pos] = ll_value

next

// Return
return(upperbound(al_uniquevalues))
end function

----------------------------------------------------------------

public function integer of_arrayunique (string as_sourcevalues[], ref string as_uniquevalues[], boolean ab_ignorecase);int            li_pos,li_cnt,li_tcnt,li_cnt2
string      ls_empty[],ls_value
boolean      lb_skip


// Initialize Return Array
as_uniquevalues = ls_empty

// Loop Through Array Values
li_tcnt = upperbound(as_sourcevalues)
for li_cnt = 1 to li_tcnt

      // Get Value
      lb_skip = FALSE
      ls_value = as_sourcevalues[li_cnt]
      if ab_ignorecase then
            ls_value = trim(lower(ls_value))
            if ls_value = "" then continue
      end if

      // Determine if Unique
      for li_cnt2 = 1 to li_pos
            if ls_value = lower(as_uniquevalues[li_cnt2]) then
                  lb_skip = TRUE
                  exit
            end if
      next
      if lb_skip then continue

      // Include
      li_pos ++
      as_uniquevalues[li_pos] = ls_value

next

// Return
return(upperbound(as_uniquevalues))
end function

Here are the other the functions that call the fully qualified function...

public function integer of_arrayunique (ref long al_return[])            ;return(of_arrayunique(al_return,al_return))
public function integer of_arrayunique (ref string as_return[])      ;return(of_arrayunique(as_return,as_return,FALSE))
public function integer of_arrayunique (ref string as_return[], boolean ab_ignorecase);return(of_arrayunique(as_return,as_return,ab_ignorecase))
0
 

Author Comment

by:Mehram
ID: 35036181
Great

The benefit of asking at EE is that you learn a lot of new things.
The of_arrayunique function has gone  easily into our user object uo_functions.

lbushby:
The creation of datastore at runtime was thrilling. I was in search of this since a long time.

U experts are lovely and Unselfish.

My best regards to both of U

(Mat)
0
 

Author Closing Comment

by:Mehram
ID: 35036287
Thanks a lot
0
 
LVL 1

Expert Comment

by:goodwinfam
ID: 35042058
Thanks,  
To appear less A.D.D. I  adjusted a few things...Please note that you may not wish to always skip NULL or empty values which is the assumption in these scripts.  The option whether or not to do so might also be a flag you pass (which I have in my actual code).  In the function handling strings you should add a line looking for a null value following "ls_value = as_sourcevalues[li_cnt]" like  (if isinull(ls_value) then ls_value = "" or if you are skipping empty values "if isinull(ls_value) then continue"...).  
0
 
LVL 1

Expert Comment

by:goodwinfam
ID: 35042188
Change "continue" to "exit" in the compare section for comparing long values above.

The final string value compare script...  
----------------
public function integer of_arrayunique (string as_sourcevalues[], ref string as_uniquevalues[], boolean ab_ignorecase, boolean ab_includeempty, boolean ab_untrimmed);int            li_cnt,li_tcnt,li_uniquecnt,li_totuniquecnt
string      ls_empty[],ls_value
boolean      lb_skip


// Initialize Return Array
as_uniquevalues = ls_empty

// Loop Through Array Values
li_tcnt = upperbound(as_sourcevalues)
for li_cnt = 1 to li_tcnt

      // Get Value
      lb_skip = FALSE
      ls_value = as_sourcevalues[li_cnt]
      if NOT(ab_untrimmed) then ls_value = trim(ls_value)
      if NOT(ab_includeempty) AND ( isnull(ls_value) or ls_value = "" ) then continue

      // Compare (this loop skipped first time through because li_totuniquecnt will = 0)
      for li_uniquecnt = 1 to li_totuniquecnt
            choose case TRUE
                  case ls_value = as_uniquevalues[li_uniquecnt]                                                                                                                                    ; lb_skip = TRUE      ; exit
                  case ab_ignorecase AND (lower(ls_value) = lower(as_uniquevalues[li_uniquecnt]))                                                                  ; lb_skip = TRUE      ; exit
                  case (ab_ignorecase AND ab_untrimmed) AND (lower(trim(ls_value)) = lower(trim(as_uniquevalues[li_uniquecnt])))      ; lb_skip = TRUE      ; exit
            end choose
      next
      if lb_skip then continue

      // Include
      li_totuniquecnt ++
      as_uniquevalues[li_totuniquecnt] = ls_value

next

// Return
return(upperbound(as_uniquevalues))
end function
0
 

Author Comment

by:Mehram
ID: 35144481
Thanks again goodwinfam
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org Go to that link and select download selenium in the right hand column That will then direct you to their download page. From that p…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
Suggested Courses

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question