Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 11-14 of 14 total

chunk function

    split: chunk: segment: func [  ; subdivide ?
        {See: CLOS pg. 937. Not that mine works the same, but that was
        the inspiration.}
        series [series!]
        size   [integer!] "The size of the chunks (last chunk may be shorter)"
        /into  "split into a set number (size) of chunks (last chunk may be longer than others)."
        /local ct cur-piece result
    ][
        ct: either into [size] [round/down divide length? series size]
        if into [size: to-integer divide length? series size]
        result: copy []
        if zero? size [return result]
        parse series [
            ct [
                copy cur-piece size skip (append/only result cur-piece) mark:
            ]
        ]
        if any [into  not zero? remainder length? series size] [
            cur-piece: copy mark
            either into
                [append last result cur-piece]
                [append/only result cur-piece]
        ]
        result
    ]

split function

    ; Gabriele's, with Andreas's ANY mod.
    split: func [string delim /local result data] [
        result: copy []
        parse/all string [
            ; The ANY bit ensures we don't insert NONE values.
            any [copy data to delim (insert tail result any [data copy ""]) delim]
            copy data to end (insert tail result any [data copy ""])
        ]
        result
    ]

Partition a String based on a regex. Similar to String#split but matches are preserved.

I've create a handy Ruby String utility. It allows you to partition a String based on a regex (similar to String#split), but it preserves the matched sub-strings (unlike split). Here it is for anyone interested:

I also posted this code on my blog


class String

  #partitions a string based on regex.  matches are included in results
  #ex. 'a b  c'.partition(/ +/) returns ['a', ' ', 'b', '  ', 'c']
  #ex. ' b '.partition(/ +/) returns [' ', 'b', ' ']
  def partition(regex)
    results = []
    s = StringScanner.new(self)
    last_pos = 0
    while(s.skip_until(regex))
      matched_size = s.matched_size
      pos = s.pos
      #add the non-delimiter string if it exists (it may not if the string starts with a delimiter)
      results << self[last_pos ... pos - matched_size] if last_pos < pos - matched_size
      #add the delimiter
      results << self[pos - matched_size ... pos]
      #update the last_pos to the current pos
      last_pos = pos
    end
    #add the last non-delimiter string if one exists after the last delimiter.  It would not have
    #been added since s.skip_until would have returned nil
    results << self[last_pos ... self.length] if last_pos < self.length
    results
  end
end

Splitting an integer list in TSQL

Revised: 2006-02-23 - fixed various bugs by using new algorithm
Often times I have a list of integers I need to pass to the database to get worked on. Such as checkboxes on a web page or some other list. I needed some TSQL that would take a text string and split it by a separator, in this case a comma. The following is the result of that need.
The way I normally use it is in a stored procedure like the one below with several text type arguments. Sometimes I use a variation designed to split a list of strings separated by a special character sequence. Image two lists, one of the ids and one of the data. You parse the first list to get a table of the ids and you parse the second list to get the data and insert/update as appropriate.

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[uspSplitIntegerList]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
   DROP PROCEDURE [dbo].[uspSplitIntegerList]
GO
                                      
SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS ON 
GO


/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-- uspSplitIntegerList
--
-- Description:
--		splits a comma separated list of integers and returns the integer list
--
-- Arguments:
--		@list_integers					- list of integers
--
-- Notes:
-- 02/22/2006 - WSR : use DATALENGTH instead of LEN throughout because LEN doesn't count trailing blanks
--
-- History:
-- 02/22/2006 - WSR : revised algorithm to account for items crossing 8000 character boundary
--
CREATE PROCEDURE uspSplitIntegerList
	@list_integers			text
AS

SET NOCOUNT ON

DECLARE @InputLen			integer			-- input text length
DECLARE @TextPos			integer			-- current position within input text
DECLARE @Chunk				varchar(8000)	-- chunk within input text
DECLARE @ChunkPos			integer			-- current position within chunk
DECLARE @DelimPos			integer			-- position of delimiter
DECLARE @ChunkLen			integer			-- chunk length
DECLARE @DelimLen			integer			-- delimiter length
DECLARE @Delimiter      varchar(3)		-- delimiter
DECLARE @ItemBegPos		integer			-- item starting position in text
DECLARE @ItemOrder		integer			-- item order in list

-- create table to hold list items
-- actually their positions because we may want to scrub this list eliminating bad entries before substring is applied
CREATE TABLE #list_items ( item_order integer, item_begpos integer, item_endpos integer )

-- process list
IF @list_integers IS NOT NULL
   BEGIN

	-- initialize
   -- notice that this loop assumes a delimiter length of 1
   -- if the delimiter is longer we have to deal with stuff like delimiters straddling the chunk boundaries
   SET @InputLen = DATALENGTH(@list_integers)
   SET @TextPos = 1
	SET @Delimiter = ','
	SET @DelimLen = DATALENGTH(@Delimiter)
   SET @ItemBegPos = 1
   SET @ItemOrder = 1
   SET @ChunkLen = 1

   -- cycle through input processing chunks
   WHILE @TextPos <= @InputLen AND @ChunkLen <> 0
      BEGIN

      -- get current chunk
      SET @Chunk = SUBSTRING(@list_integers, @TextPos, 8000)

      -- setup initial variable values
      SET @ChunkPos = 1
      SET @ChunkLen = DATALENGTH(@Chunk)
      SET @DelimPos = CHARINDEX(@Delimiter, @Chunk, @ChunkPos)

      -- loop over the chunk, until the last delimiter
      WHILE @ChunkPos <= @ChunkLen AND @DelimPos <> 0
         BEGIN

			-- insert position
         INSERT INTO #list_items (item_order, item_begpos, item_endpos)
         VALUES (@ItemOrder, @ItemBegPos, (@TextPos + @DelimPos - 1) - 1)
         
         -- adjust positions
         SET @ItemOrder = @ItemOrder + 1
         SET @ItemBegPos = (@TextPos + @DelimPos - 1) + @DelimLen
         SET @ChunkPos = @DelimPos + @DelimLen
      
         -- find next delimiter      
         SET @DelimPos = CHARINDEX(@Delimiter, @Chunk, @ChunkPos)

         END

      -- adjust positions
      SET @TextPos = @TextPos + @ChunkLen

      END

	-- handle last item
   IF @ItemBegPos <= @InputLen
      BEGIN

      -- insert position
      INSERT INTO #list_items (item_order, item_begpos, item_endpos)
      VALUES (@ItemOrder, @ItemBegPos, @InputLen)

      END

	-- delete the bad items
   DELETE FROM #list_items
   WHERE item_endpos < item_begpos

   -- return list items
	SELECT CAST(SUBSTRING(@list_integers, item_begpos, (item_endpos - item_begpos + 1)) AS integer) AS item_integer, item_order, item_begpos, item_endpos
   FROM #list_items
   WHERE ISNUMERIC(SUBSTRING(@list_integers, item_begpos, (item_endpos - item_begpos + 1))) = 1
   ORDER BY item_order

   END

DROP TABLE #list_items

RETURN

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO
« Newer Snippets
Older Snippets »
Showing 11-14 of 14 total