Combining String data

Post

Posted
Rating:
#1 (In Topic #1107)
Enthusiast
AndyGable is in the usergroup ‘Enthusiast’
Hi Everyone

Just wanted to run a quick problem / question past you all

I have a data file that holds data in the following format

barcode|qty (eg 50201600|1)

What I would like to do is is read the file in (as this can be anything from 1 line to 5,000 lines) and I would like to combine the qtys for items that have already been read in

What would be the best way to do that? Can I do it with a Array or does it have to be a database table?

For example

5018374320766|1
50201600|2
99998|1
99999|2
5018374320766|2
50201600|1


so when it is out putted I would get


5018374320766|3
50201600|3
99998|1
99999|2
Online now: No Back to the top

Post

Posted
Rating:
#2
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
 I'd do it using a collection. Read each line and split it into a barcode and a quantity. Then using the barcode as the key and the quantity as the value, if the key is not in the collection already then add the key with the value 0. Then update the (now existing key) adding the quantity to the value. Done.

Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Guru
cogier is in the usergroup ‘Guru’
You can do it with arrays. This is my solution, maybe someone can come up with a simpler version but this does work.

Code (gambas)

  1. ' Gambas class file
  2.  
  3. 'Contents of file BCode.txt
  4. ' 5018374320766|1
  5. ' 50201600|2
  6. ' 99998|1
  7. ' 99999|2
  8. ' 5018374320766|2
  9. ' 50201600|1
  10. ' 5018374320766|5
  11. ' 99999|2
  12. ' 547892|9
  13. ' 99999|2
  14. ' 547892|5
  15.  
  16. Public Sub Form_Open()
  17.  
  18.   Dim sList As String[] = Split(File.Load(Application.Path &/ "BCode.txt"), gb.NewLine, "", True).Sort() 'Load the file into the array sList
  19.   Dim bBCode As New String[]
  20.   Dim iQty As New Integer[]
  21.   Dim iLoop, iFind As Integer
  22.  
  23.   For iLoop = 0 To sList.Max
  24.     iFind = bBCode.Find(Split(sList[iLoop], "|")[0])  
  25.     If iFind > -1 Then                                      'Does the Barcode exists in the new array
  26.       iQty[iFind] += Val(Split(sList[iLoop], "|")[1])       'It does so just alter the quantity
  27.     Else
  28.       bBCode.Add(Split(sList[iLoop], "|")[0])               'It doesn't so add to BBcode array and..
  29.       iQty.Add(Split(sList[iLoop], "|")[1])                 'Add the quantity to iQty array  
  30.     Endif
  31.   Next
  32.  
  33.   sList.Clear                                               'Clear sList
  34.  
  35.   For iLoop = 0 To bBCode.Max                               'Rebuild sList with the new data
  36.     sList.Add(bBCode[iLoop] & "|" & Str(iQty[iLoop]))
  37.   Next
  38.  
  39.   Print sList.Join(gb.Newline)                              'Print out the array
  40.  
  41.  
  42. ' Output
  43. ' 5018374320766|8
  44. ' 50201600|3
  45. ' 547892|14
  46. ' 99998|1
  47. ' 99999|6
  48.  
Online now: Yes Back to the top

Post

Posted
Rating:
#4
Regular
vuott is in the usergroup ‘Regular’
Maybe even with :? this code:

Code (gambas)

  1. 'Contents of file BCode.txt
  2. ' 5018374320766|1
  3. ' 50201600|2
  4. ' 99998|1
  5. ' 99999|2
  6. ' 5018374320766|2
  7. ' 50201600|1
  8. ' 5018374320766|5
  9. ' 99999|2
  10. ' 547892|9
  11. ' 99999|2
  12. ' 547892|5
  13.  
  14. Public Sub Main()
  15.  
  16.   Dim s As String = File.Load(Application.Path &/ "BCode.txt")
  17.   Dim ss, sc As String[]
  18.   Dim c, n As Short
  19.  
  20.   ss = Split(s, gb.NewLine)
  21.   ss.Remove(ss.Max, 1)
  22.   While ss.Count > 0
  23.     c = 0
  24.     n = 0
  25.     sc = Scan(ss[0], "*|*")
  26.     Repeat
  27.       If Scan(ss[c], "*|*")[0] = sc[0] Then
  28.         n += Val(Scan(ss[c], "*|*")[1])
  29.         ss.Remove(c, 1)
  30.         Dec c
  31.       Endif
  32.       Inc c
  33.     Until c > ss.Max
  34.     Print sc[0]; "|"; n
  35.   Wend
  36.  

Europaeus sum !

<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
Online now: No Back to the top

Post

Posted
Rating:
#5
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
For the sake of it

Code (gambas)

  1. ' Gambas module file
  2.  
  3.  
  4. Public Sub Main()
  5.  
  6.   Dim sLines As String[] = Split(File.Load("./data.txt"), "\n")
  7.  
  8.   SumOverBCode(sLines)
  9.  
  10.   For Each $totals
  11.     Print $totals.Key; "|"; $totals[$totals.Key]
  12.   Next
  13.  
  14.  
  15. Private Sub SumOverBCode(data As String[])
  16.  
  17.   Dim aWorkline As String[]
  18.  
  19.   For idx As Integer = 0 To data.Max
  20.     aWorkline = Split(data[idx], "|")
  21.     If Not $totals.Exist(aWorkline[0]) Then
  22.       $totals.Add(0, aWorkline[0])
  23.     Endif
  24.     $totals[aWorkline[0]] += aWorkline[1]
  25.   Next
  26.  
  27.  

Output:
5018374320766|8
50201600|3
99998|1
99999|6
547892|14

Total duration = 179ms

Online now: No Back to the top

Post

Posted
Rating:
#6
Avatar
Guru
cogier is in the usergroup ‘Guru’
Wow! You now have 3 options to pick from.

A couple of points.

vuott: - Your code works perfectly if line 22 ss.Remove(ss.Max, 1) is removed!

thatBruce: - Your code will look better if you use the gb rather than the </> button. (I have edited your post above).
<IMG src="https://www.cogier.com/gambas/gb_button.png"> </IMG>
Online now: Yes Back to the top

Post

Posted
Rating:
#7
Regular
vuott is in the usergroup ‘Regular’

cogier said

vuott: - Your code works perfectly if line 22 ss.Remove(ss.Max, 1) is removed!
The text file, which I load, is structured exactly like this:
<COLOR color="#800000">5018374320766|1
50201600|2
99998|1
99999|2
5018374320766|2
50201600|1
5018374320766|5
99999|2
547892|9
99999|2
547892|5
</COLOR>

If I do not enter the command line "ss.Remove(ss.Max, 1) ", I get the error "Out of Bound ".

However, I can remove it, but I have to add the RTrim() function to the string assignment in the first declaration of the local variable 's'.
If not, I still get the error "Out of Bound ".

Code (gambas)

  1. Public Sub Main()
  2.  
  3.   Dim s As String = RTrim(File.Load(Application.Path &/ "BCode.txt"))
  4.   Dim ss, sc As String[]
  5.   Dim c, n As Short
  6.  
  7.   ss = Split(s, gb.NewLine)
  8.  
  9.   While ss.Count > 0
  10.     c = 0
  11.     n = 0
  12.     sc = Scan(ss[0], "*|*")
  13.     Repeat
  14.       If Scan(ss[c], "*|*")[0] = sc[0] Then
  15.         n += Val(Scan(ss[c], "*|*")[1])
  16.         ss.Remove(c, 1)
  17.         Dec c
  18.       Endif
  19.       Inc c
  20.     Until c > ss.Max
  21.     Print sc[0]; "|"; n
  22.   Wend
  23.  

Europaeus sum !

<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
Online now: No Back to the top

Post

Posted
Rating:
#8
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
 At a guess, I'd say that one of you has a blank line at the end of the file and one doesn't.  In other words a Cr or whatever on the last data line.
If that is the case then I find the best way to to handle that is in the initial file load when the file string is split by line endings, just by ignoring nulls in the split.

Online now: No Back to the top

Post

Posted
Rating:
#9
Avatar
Guru
cogier is in the usergroup ‘Guru’

thatbruce said

At a guess, I'd say that one of you has a blank line at the end of the file and one doesn't.  In other words a Cr or whatever on the last data line.
If that is the case then I find the best way to to handle that is in the initial file load when the file string is split by line endings, just by ignoring nulls in the split.

I agree and that is what is in my code. Below is one change I have made to vuott's code that deals with the 'extra' lines.

Code (gambas)

  1. 'Contents of file BCode.txt
  2. ' 5018374320766|1
  3. '
  4. ' 50201600|2
  5. ' 99998|1
  6. ' 99999|2
  7. ' 5018374320766|2
  8. ' 50201600|1
  9. '
  10. ' 5018374320766|5
  11. ' 99999|2
  12. ' 547892|9
  13. '
  14. ' 99999|2
  15. '
  16. ' 547892|5
  17. '
  18.  
  19. Public Sub Main()
  20.  
  21.   Dim s As String = RTrim(File.Load(Application.Path &/ "BCode.txt"))
  22.   Dim ss, sc As String[]
  23.   Dim c, n As Short
  24.  
  25.   'ss = Split(s, gb.NewLine)
  26.   ss = Split(s, gb.NewLine, "", True) ''It's the TRUE that does the work.
  27.  
  28.   While ss.Count > 0
  29.     c = 0
  30.     n = 0
  31.     sc = Scan(ss[0], "*|*")
  32.     Repeat
  33.       If Scan(ss[c], "*|*")[0] = sc[0] Then
  34.         n += Val(Scan(ss[c], "*|*")[1])
  35.         ss.Remove(c, 1)
  36.         Dec c
  37.       Endif
  38.       Inc c
  39.     Until c > ss.Max
  40.     Print sc[0]; "|"; n
  41.   Wend  
  42.  
Online now: Yes Back to the top
1 guest and 0 members have just viewed this.