If I was to have a list of objects with the following properties:
SomeClass.ID
SomeClass.Name
The .ID can be an integer while .Name can be a string, is there a way to sort the objects so that any 0 .ID is sorted and placed AFTER the non-zero ID numbers?
Yes, you can use System.Linq:
Dim sorted = From o In yourObjectList
Order By o.Id = 0, o.Id
yourObjectList = sorted.ToList()
That's a conditional order, because o.Id = 0 will evaluate to either True or False. You want the non-zero first, so order Ascending(default) since True is "greater than" False.
This is the same in the (in VB.NET ugly) method syntax:
yourObjectList = yourObjectList.
OrderBy(Function(o) o.Id = 0).
ThenBy(Function(o) o.Id).
ToList()
You can also rewrite it to use the conditional operator, if that's clearer for you:
yourObjectList = yourObjectList.
OrderBy(Function(o) If(o.Id = 0, 1, 0)).
ThenBy(Function(o) o.Id).
ToList()
The If-operator it treats Id's with zero as 1 and all others as 0, so the <> 0 will come first.
Related
df = df.assign[test = np.select[df.trs = 'iw' & df.rp == 'yu'],[1,0],'null']
I want if df.trs == iw' and df.rp == 'yu'` than new column should be created should be 0 else 1 only for condotion fullfilling row not every row
I tried no.slect and with condition array. But not getting desired output
You don't need numpy.select, a simple boolean operator is sufficient:
df['test'] = (df['trs'].eq('iw') & df['rp'].eq('yu')).astype(int)
If you really want to use numpy, this would require numpy.where:
df['test'] = np.where(df['trs'].eq('iw') & df['rp'].eq('yu'), 1, 0)
I have a report in which one of the columns returns a DB field which can be 1 of 3 possible outcomes - 1, 0 or blank/"".
From what I can see, I think the problem here is that the field is blank rather than a NULL value, so any expressions I use seem to result in a #Error.
So far I have managed two different expressions which yield two halves of the results I need:
=IIF(Fields!Field1.Value = 1, "Yes", IIF ({Fields!Field1.Value = 0}, "No", "Unanswered"))
The above gets me 1 = "Yes", 2 = "No" and "" = #Error.
=IIF(Fields!Field1.Value="","Unanswered",Fields!Field1.Value)
This second one gets me 1 = 1, 0 = 0 and "" = "Unanswered".
Is there a way I can combine these and have the results appearing as 1 = "Yes", 0 = "No" and "" = "Unanswered"?
Any advice is appreciated!
Try using this SWITCH expression.
=SWITCH (
Fields!Field1.Value = 1, "Yes",
Fields!Field1.Value = 0, "No",
True, "Unanswered"
)
The final True acts like and else.
If this does not work, you may need to cast the field to text and check as follows
e.g. CStr(Fields!Field1.Value) = "1", "Yes",
I'm sorting an array using code like this:
Array.Sort(arr, 0, intEndingPosition, New myIComparer)
I want the sorting to start with index 0 and end with index intEndingPosition. However, the last element arr(intEndingPosition) was left out and did not get sorted. Why?
intEndingPosition is calculated beforehand like this:
Dim StringOfConcern As String
Dim OneChar(65534), FrqOne(65534) As String
Dim CntNewOnes, CntRptOnes As Integer
Dim c As Char
Dim i, j As Integer
Dim isNew As Boolean
StringOfConcern = TextBox1.Text
OneChar(0) = CStr(StringOfConcern(0))
FrqOne(0) = 1
i = 0
j = 0
For Each c In StringOfConcern.Substring(1)
isNew = True
For j = 0 To i Step 1
If CStr(c) = OneChar(j) Then
isNew = False
FrqOne(j) += 1
Exit For
End If
Next j
If isNew = True Then
i += 1
OneChar(i) = CStr(c)
FrqOne(i) = 1
End If
Next c
CntNewOnes = i + 1
CntRptOnes = 0
For i = 0 To CntNewOnes - 1 Step 1
If FrqOne(i) > 1 Then CntRptOnes += 1
Next i
The sorting follows here. The code in my original question is only illustrative. The actual sorting is:
Array.Sort(FrqOne, OneChar, 0, CntNewOnes - 1)
Array.Reverse(FrqOne, 0, CntNewOnes - 1)
Array.Reverse(OneChar, 0, CntNewOnes - 1)
Note the method declaration for Array.Sort
Public Shared Sub Sort (
array As Array,
index As Integer,
length As Integer,
comparer As IComparer
)
The third parameter is the number of elements in the range to sort (length) not the end index as you suggest.
So let's assume for a minute that your intEndingPosition is 4. This means you're expecting to sort 5 elements i.e. elements at indices 0, 1, 2, 3, 4. However, the number 4 is the length and not the end index thus you're only sorting elements at indices 0, 1, 2, 3.
This explains why you're observing that the elements being sorted is one shorter than you expected.
Put it simply the third parameter should specify the length of elements to sort and not the end index.
Another Example:
Consider the Substring method of the String class:
Public Function Substring (
startIndex As Integer,
length As Integer
) As String
Then assume we have this piece of code:
Dim temp As String = "testing"
Dim result As String = temp.Substring(0, 4)
result is now a string containing 4 characters as 4 in the Substring call indicates the length that should be retrieved as opposed to the end index.
Had 4 been the end index then you'd expect result to contain 5 characters.
I have a simple (well easy, not simple) query of "not in" on related tables.
SELECT CompetencyID, CompetencyName FROM Competency
WHERE (Deleted = 0) AND (CompanyID = 1) AND (CompetencyID NOT IN(SELECT CompetencyID
FROM CompetencyGroups WHERE (Deleted = 0) AND (CompanyID = 1) AND (GroupID = 1))) AND
(ParentID = 0) ORDER BY CompetencyName
In SQL I get the list that I need with remaining items not in the group. Now I want to bind this to a DataGrid using EF5.
I cannot get the query syntax properly (Using VB.net) to list the ID and the Name of the Competency...
Converted the provided c# answer to VB:
Dim excludeList = context.CompetencyGroups.Where(Function(x) x.Deleted = False And x.GroupID = GroupID).Select(Function(x) x.CompetencyID).ToArray
Dim results = context.Competencies.Where(Function(c) Not excludeList.Contains(c.CompetencyID) And c.Deleted = False And c.CompanyID = 1 And c.ParentID = 0).OrderBy(Function(c) c.CompetencyName)
GridView2.DataSource = results
GridView2.DataBind()
Hope this helps someone in the future. Took me about 4 hours to search, ask and convert...
Something like
var excludeList = context.CompetencyGroups.Where(x => x....).Select(x => x.CompetencyID).ToArray();
var results = context.Competency.Where(x => !excludeList.Contains(x.CompetencyID));
Update: Somebody else edited this and then someone rejected it, but the edit was a good one (to select the value)
If you need the Cast to make an array of Integers.
Dim excludeList = context.CompetencyGroups.Cast(Of CompentencyGroup).Select(Function(x) x.CompetencyID).ToArray()
Dim results = context.Competency.Where(Function(x) Not excludeList.Contains(x.CompetencyID))
In the following linq query I have a division by zero exception wich I can't seem to code around. It occurs when the Sum of fldDevider returns 0.
Dim lstToReturn As List(Of MonthData)
lstToReturn = (
From myRow In dtSpotData.AsEnumerable()
Group myRow By myRow.Field(Of DateTime)(fldstartdate).Month Into Group
Select New MonthData() With {
.Month = Month,
.ValuePerMonth =
(
Group.Sum(Function(dr) dr.Field(Of [Decimal])(fldSomeGeneralValue)) /
(
Group.Sum(Function(dr) CDec(dr.Field(Of String)(fldDevider)))
)
)
}
).ToList()
How can I Make sure the ValuePerMonth field is 0 when the Group.Sum(Function(dr) CDec(dr.Field(Of String)(fldDevider))) function returns a 0. Or how do I return a 1 for Sum fldDevider if it is actually 0.
Some tips on how to do better conversions from string to decimal are welcome too.
I am used to C# syntax but I would use a 'let' to capture the value of the dividing number and only use it if it is greater than zero, and otherwise use 1.
Dim lstToReturn As List(Of MonthData)
lstToReturn = (
From myRow In dtSpotData.AsEnumerable()
Group myRow By myRow.Field(Of DateTime)(fldstartdate).Month Into Group
Let div = Group.Sum(Function(dr) CDec(dr.Field(Of String)(fldDevider)))
Select New MonthData() With {
.Month = Month,
.ValuePerMonth =
(
Group.Sum(Function(dr) dr.Field(Of [Decimal])(fldSomeGeneralValue)) / If(div > 0, div, 1)
)
}
).ToList()