[PB4] Split() and Join() commands

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
flype
Beiträge: 15
Registriert: 28.02.2006 23:03
Wohnort: France, Nantes

[PB4] Split() and Join() commands

Beitrag von flype »

Code: Alles auswählen

; Split() functions, Purebasic 4.0+

Macro CountArray(array)
  ( PeekL( @array-8 ) )
EndMacro

Procedure.l SplitArray(array.s(1), text.s, separator.s = ",") ; String to Array
  
  Protected index.l, size.l = CountString(text, separator)
  
  ReDim array.s(size)
  
  For index = 0 To size
    array(index) = StringField(text, index + 1, separator)
  Next
  
  ProcedureReturn size
  
EndProcedure
Procedure.s JoinArray(array.s(1), separator.s = ",") ; Array to String
  
  Protected index.l, result.s, size.l = CountArray(array()) - 1
  
  For index = 0 To size
    result + array(index)
    If (index < size)
      result + separator
    EndIf
  Next
  
  ProcedureReturn result
  
EndProcedure
Procedure.l SplitList(list.s(), text.s, separator.s = ",") ; String to List
  
  Protected index.l, size.l = CountString(text, separator)
  
  For index = 0 To size
    If AddElement(list())
      list() = StringField(text, index + 1, separator)
    EndIf
  Next
  
  ProcedureReturn size
  
EndProcedure
Procedure.s JoinList(list.s(), separator.s = ",") ; List to String
  
  Protected result.s, size.l = CountList(list()) - 1
  
  ForEach list()
    result + list()
    If (ListIndex(list()) < size)
      result + separator
    EndIf
  Next
  
  ProcedureReturn result
  
EndProcedure

; Examples

string.s = "abc,defg,hi,jklmop,qrs,tuv,wxyz"

; string -> array -> string

Dim a.s(0)

size.l = SplitArray(a(), string, ",")

For i = 0 To size
  Debug a(i)
Next

Debug JoinArray(a())

; string -> list -> string

NewList b.s()

If SplitList(b(), string)
  ForEach b()
    Debug b()
  Next
EndIf

Debug JoinList(b())

;--
Bild Bild
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

Hello flype,

thank you for sharing your code! :allright:

Greetings ... Kiffi
flype
Beiträge: 15
Registriert: 28.02.2006 23:03
Wohnort: France, Nantes

Beitrag von flype »

Php Syntax :

http://php.net/manual/en/function.implode.php
http://php.net/manual/en/function.explode.php

Code: Alles auswählen

; 
; Join()/Split()
; 
; Php Syntax:
; implode.s( glue.s, pieces.s(1) )
; explode.l( separator.s, string.s , limit.l = 0 )
; 
; http://php.net/manual/en/function.implode.php
; http://php.net/manual/en/function.explode.php
; 

Macro CountArray(array)
  ( PeekL( @array-8 ) )
EndMacro

Procedure.l explode_list(list.s(), separator.s, string.s, limit.l = 0) ; String to List
  
  Protected index.l, size.l = CountString(string, separator)
  
  If (limit > 0)
    size = limit - 1
  ElseIf (limit < 0)
    size + limit
  EndIf
  
  For index = 0 To size
    If AddElement(list())
      list() = StringField(string, index + 1, separator)
    EndIf
  Next
  
  ProcedureReturn size
  
EndProcedure
Procedure.s implode_list(glue.s, pieces.s()) ; List to String
  
  Protected string.s, size.l = CountList(pieces()) - 1
  
  ForEach pieces()
    string + pieces()
    If (ListIndex(pieces()) < size)
      string + glue
    EndIf
  Next
  
  ProcedureReturn string
  
EndProcedure

Procedure.l explode_array(array.s(1), separator.s, string.s, limit.l = 0) ; String to Array
  
  Protected index.l, size.l = CountString(string, separator)
  
  If (limit > 0)
    size = limit - 1
  ElseIf (limit < 0)
    size + limit
  EndIf
  
  ReDim array.s(size)
  
  For index = 0 To size
    array(index) = StringField(string, index + 1, separator)
  Next
  
  ProcedureReturn size
  
EndProcedure
Procedure.s implode_array(glue.s, pieces.s(1)) ; Array to String
  
  Protected index.l, string.s, size.l = CountArray(pieces()) - 1
  
  For index = 0 To size
    string + pieces(index)
    If (index < size)
      string + glue
    EndIf
  Next
  
  ProcedureReturn string
  
EndProcedure

; Examples

input.s = "feel the power of purebasic :-)"

; string -> array -> string

Dim a.s(0)

size.l = explode_array(a(), " ", input, -3)

For i = 0 To size
  Debug a(i)
Next

Debug implode_array("  =|=  ", a())

; string -> list -> string

NewList b.s()

If explode_list(b(), " ", input, 5)
  ForEach b()
    Debug b()
  Next
EndIf

Debug "[" + implode_list("][", b()) + "]"

;--
Bild Bild
Amon
Beiträge: 26
Registriert: 12.05.2005 21:29

Beitrag von Amon »

great code, thanx 4 sharing

do you see any possibility to do the same with a separator.s with len > 1 ?

(like the original php functions)
flype
Beiträge: 15
Registriert: 28.02.2006 23:03
Wohnort: France, Nantes

Beitrag von flype »

yes i see one possibility :

first, we have to 'patch' the builtin command 'StringField()' with a new custom macro.

so, add this code at the top of the above source code and it should work (not tested).

Code: Alles auswählen

Macro StringField(string, index, separator)
  StringFieldEx(string, index, separator)
EndMacro

Procedure.s StringFieldEx(string.s, index.l, sep.s)
  
  Protected i.l, pos.l, field.s, lSep.l = Len(sep)
  
  For i = 1 To index
    pos = FindString(string, sep, 1)
    If pos
      field = Left(string, pos - 1)
    Else
      field = string
    EndIf
    string = Mid(string, pos + lSep, Len(string))
  Next
  
  ProcedureReturn field
  
EndProcedure
not really optimized but should do the trick :wink:
Bild Bild
Antworten