问题
I have an array of data brought into my VB .Net program that follows the following format.
Order No.|Description|Colour|Size|Total Qty.|Order Date|Expected D.D.
2273448|NOK OPAQUE KNEE HIGH |BLACK |X |001 |02/12/2013 |05/12/2013
2231428|UX XR WARM HOLD UPS |NAVY |ONE SIZE |001 |02/12/2013 |05/12/2013
2231428|NHS SOFTHOLD HOLD-UP |BLACK |X |001 |02/12/2013 |05/12/2013
2265640|KX XR WARM TIGHTS |BLACK |XXL |001 |02/12/2013 |05/12/2013
2273448|NOK OPAQUE KNEE HIGH |BLACK |X |001 |02/12/2013 |05/12/2013
2231428|NHS SOFTHOLD HOLD-UP |BLACK |X |001 |02/12/2013 |05/12/2013
2231428|NHS SOFTHOLD HOLD-UP |NATURAL |X |001 |02/12/2013 |05/12/2013
2267461|WF-01 FLIP FLOP |BLACK |13 |001 |02/12/2013 |05/12/2013
2231428|NHS SOFTHOLD HOLD-UP |NATURAL |X |001 |02/12/2013 |05/12/2013
2273007|CR COTTON-RICH SOCK |BLACK |4-7 |001 |02/12/2013 |06/12/2013
2273127|TH THERMAL SOCK |MOSS |6-11 |001 |02/12/2013 |06/12/2013
This is a pre-formatted piped text file that I have no control over.
I am trying to bring this data into a VB DataGrid, but before I do, I want to de-dupe the values, whilst counting them, so I can display only pertinent data, without duplicate rows, so that the program user can then select the rows and work on all the associated rows (i.e. reducing the potential for human error.
The expected output to the DataGrid, based on the above, would be something like...
Order No | Lines on Order | Order Date | Expected Date
2273448 |2 |02/12/2013 |05/12/2013
2231428 |5 |02/12/2013 |05/12/2013
2265640 |1 |02/12/2013 |05/12/2013
2267461 |1 |02/12/2013 |05/12/2013
2273007 |1 |02/12/2013 |06/12/2013
2273127 |1 |02/12/2013 |06/12/2013
Here is the portion of the form code that is opening the file and retrieving the data...
Dim JDW_Row As String
Dim JDW_RowValues() As String
' Process JDW Order File into DataGrid
Dim JDW_Reader As IO.StreamReader = New IO.StreamReader(File.OpenRead(FullPath), System.Text.Encoding.Default)
' Skip Header
JDW_Reader.ReadLine()
' Start reading file contents
Do Until JDW_Reader.EndOfStream
' read a record and split into fields
JDW_Row = JDW_Reader.ReadLine()
JDW_RowValues = Split(JDW_Row, "|")
Loop
I get that for each member of JDW_RowValues, I need to ask 'have I seen you before' by writing it to an array and incrementing an associated counter or array value if its encountered again but I'm not sure of the code in VB .NET.
Can anyone suggest the best method?
回答1:
Class OrderItem
Public Property OrderNo As String ' ???
Public Property Quantity As Integer
Public Property OrderDate As DateTime
Public Property ExpectedDate As DateTime
Sub New(newOrderNo)
OrderNo = newOrderNo
End Sub
End Class
Friend colOrderItems as New Dictionary(Of String, OrderItem)
' ... pseudo for adding in the loop
Dim item as OrderItem
Do Until JDW_Reader.EndOfStream
If colOrderItems.ContainsKey(newOrderIDRead) Then
' increment quatity
colOrderItems(newOrderIDRead).Quantity += newQuanReadValue
Else
' add a new one
item = New OrderItem(newOrderIDRead)
item.Quantity = newQuanReadValue
...
colOrderItems.Add(newOrderIDRead, item)
End If
Loop
The dictionary helps weed out duplicates because only one key of that value (OrderID) is allowed, and it is easy to find existing ones. A List(of OrderItem)
would also work, but it does not inherently keep out dupes (which also partly depends on the definition of a dupe).
回答2:
You could create an Object for your duped data and keep track of the count via a List(of YourObject).
Here is an example:
Public Class DupedOrderData
Public Property OrderID As Integer
Public Property LinesOnOrder As Integer
Public Property OrderDate As Date
Public Property ExpectedDate As Date
End Class
Then before your loop:
Dim lstOrders As New List(Of DupedOrderData)
Then in your loop:
Dim JDW_ROW As List(Of String) = JDW_Reader.ReadLine().Split("|").ToList()
'Already in List (LINQ Query)?
Dim objOrder As DupedOrderData = (From objTarget As DupedOrderData In lstOrders _
Where objTarget.OrderID = JDW_ROW(0)).FirstOrDefault()
If objOrder Is Nothing Then
'Add to List
objOrder = New DupedOrderData
With objOrder
.ExpectedDate = CDate(JDW_ROW(6))
.LinesOnOrder = 1
.OrderDate = CDate(JDW_ROW(5))
.OrderID = JDW_ROW(0)
End With
lstOrders.Add(objOrder)
Else
'Increment Count
objOrder.LinesOnOrder += 1
End If
来源:https://stackoverflow.com/questions/20403945/manipulate-and-dedupe-array-of-data-for-display-into-datagrid