I have the below table,
Name Consumed
A Flavour 1
B Flavour 2
C Flavour 1
C Flavour 3
A Flavour 3
B Flavour 1
C Flavour 3
A Flavour 2
A Flavour 1
C Flavour 1
A Flavour 1
B Flavour 2
Where in the first column I have the name of the persons and in the second column the Flavour preferred by them. I want to generate the below table, with Flavours as columns and find the sum of the Flavours preferred by each person. I know the solution to these using SQL, however I'm looking for a solution using LINQ VB.Net.
Name Flavour 1 Flavour 2 Flavour 3
A 3 1 1
B 1 2 0
C 2 0 2
SQL Query for achieving the above result,
SELECT Name,
SUM(CASE WHEN Consumed='Flavour 1' THEN 1 ELSE 0) AS Flavour 1,
SUM(CASE WHEN Consumed='Flavour 2' THEN 1 ELSE 0) AS Flavour 2,
SUM(CASE WHEN Consumed='Flavour 3' THEN 1 ELSE 0) AS Flavour 3
GROUP BY Name
Below is the LINQ query,
Dim query = (From row In dtMain.AsEnumerable
Let Flavour_1 = IIf(row.Field(Of String)("Consumed") = "1", 1, 0)
Let Flavour_2 = IIf(row.Field(Of String)("Consumed") = "2", 1, 0)
Let Flavour_3 = IIf(row.Field(Of String)("Consumed") = "3", 1, 0)
Group row By Code = row.Field(Of String)("Name")
Into freq = Group Select .Code = Code, .Count = freq.Count()).ToList
My difficulty is in how to aggregate the temporary variables Flavour_1, Flavour_2 and Flavour_3 using SUM function and group it by Name.
Given the following data:
Dim table = {
New With { .Name = "A", .Consumed = "Flavor 1" },
New With { .Name = "B", .Consumed = "Flavor 2" },
New With { .Name = "C", .Consumed = "Flavor 1" },
New With { .Name = "C", .Consumed = "Flavor 3" },
New With { .Name = "A", .Consumed = "Flavor 3" },
New With { .Name = "B", .Consumed = "Flavor 1" },
New With { .Name = "C", .Consumed = "Flavor 3" },
New With { .Name = "A", .Consumed = "Flavor 2" },
New With { .Name = "A", .Consumed = "Flavor 1" },
New With { .Name = "C", .Consumed = "Flavor 1" },
New With { .Name = "A", .Consumed = "Flavor 1" },
New With { .Name = "B", .Consumed = "Flavor 2" }
}
the query you're looking for is:
Dim result = From e In table
Group e By Name = e.Name Into g = group
Select New With
{
.Name = Name,
.Flavour1 = g.Count(Function(x) x.Consumed = "Flavor 1"),
.Flavour2 = g.Count(Function(x) x.Consumed = "Flavor 2"),
.Flavour3 = g.Count(Function(x) x.Consumed = "Flavor 3")
}
It's quite similar to your SQL (group, then aggregate), but you use Count instead of SUM.
You don't need a Let.
Related
data class Fruit(val name: String, val price: Int)
val fruits = arrayOf(Fruit(name = "Apple", price = 2), Fruit(name = "Grape", price = 3), Fruit(name = "Bananna", price = 4))
for (index in fruits.indices)
textView.text = fruits[index].name
Output = Bananna
I cant seem to get all elements of "Name" to reflect in the Textview
Eg.
Apple, Grape, Pear
I manage to figure it out !
val fruitNamesonly: MutableList<String> = ArrayList()
for (item in fruits) {
val token = item.name
FruitNamesonly.add(token)
}
val fruitNamesonly will be the vaulable you use for what ever
I am putting some results together in a nested list (with arrays). The expected results must be EXACTLY as follows:
{
"item1": "TEXT",
"item2": "MORE TEXT",
"item3": [
"STILL TEXT"
],
"item4": [
"TEXT AGAIN"
],
"values": [
{
"start": 0,
"end": 99
}
]
}
I put all my results together like this:
listToJson <- c(list(item1 = "TEXT",
item2 = "MORE TEXT",
item3 = "STILL TEXT",
item4 = "TEXT AGAIN",
values = list(start = 99,
end = 0)))
write_json(listToJson, path = "test.json", auto_unbox = TRUE , null = "null")
The problem is that the results doesn't have array elements (see below). item3 and item4 should be arrays. How can I change my code to get the expected results in that exact format?
{
"item1":"TEXT",
"item2":"MORE TEXT",
"item3":"STILL TEXT",
"item4":"TEXT AGAIN",
"values":{
"start":99,
"end":0}
}
You can just use as.array for those specific items.
library(jsonlite)
listToJson <- c(
list(
item1 = "TEXT",
item2 = "MORE TEXT",
item3 = as.array("STILL TEXT"),
item4 = as.array("TEXT AGAIN"),
values = as.array(list(start = 99,
end = 0))
)
)
write_json(listToJson, path = "test.json", auto_unbox = TRUE , null = "null")
Output
{
"item1":"TEXT",
"item2":"MORE TEXT",
"item3":[
"STILL TEXT"
],
"item4":[
"TEXT AGAIN"
],
"values":[
{
"start":0,
"end":99
}
]
}
I am working on an app which requires TreeView.
I'm able to generate the Treeview but facing issue with dynamically updating the treeview based on underlying dataset change.
Classes:
data class Channels(
val channel: Channel? = null
)
data class Channel(
val id: String? = null,
val name: String? = null,
val parentChannelId: String? = null
)
Data List :
var channels = observableListOf(
Channels(channel = Channel(id = "pc1", name = "P Channel 1")),
Channels(channel = Channel(id = "c11", name = "Child 1-1", parentChannelId = "pc1")),
Channels(channel = Channel(id = "c12", name = "Child 1-2", parentChannelId = "pc1")),
Channels(channel = Channel(id = "c121", name = "Child 1-2-1", parentChannelId = "c12")),
Channels(channel = Channel(id = "c111", name = "Child 1-1-1", parentChannelId = "c11")),
Channels(
channel = Channel(
id = "c1111",
name = "Child 1-1-1-1",
parentChannelId = "c111"
)
),
Channels(channel = Channel(id = "pc2", name = "P Channel 2")),
Channels(channel = Channel(id = "pc3", name = "P Channel 3")),
Channels(channel = Channel(id = "c31", name = "Child 3-1", parentChannelId = "pc3"))
)
Treeview :
treeview<Channels> {
isShowRoot = false
root = TreeItem()
cellFormat { text = it.channel?.name }
populate { parent ->
if (parent == root) channels.filter {
it.channel?.parentChannelId == null
} else channels.filter {
it.channel?.parentChannelId == parent.value?.channel?.id
}
}
}
Now when I modify the channels list, treeview doesn't gets updated.
I've been stuck on this since 3-4 days.
Please help.
When i set line chart from server side code then chart display in single column and not proper
for this we use below code:
Dim chart1 As Highcharts = New Highcharts("chart1")
chart1.InitChart(New Chart() With {
.PlotShadow = False,
.Type = ChartTypes.Spline,
.BackgroundColor = New BackColorOrGradient(New Gradient() With { _
.LinearGradient = {0, 0, 0, 400}, _
.Stops = New Object(,) {{0, Color.FromArgb(255, 96, 96, 96)}, {1, Color.FromArgb(255, 16, 16, 16)}} _
})})
chart1.SetTitle(New Title() With {.Text = "<spam style=""color:White;"">Money Utilization Report</spam>"})
Dim series As Series() = New Series(Ds.Tables(0).Rows.Count - 1) {}
Min1 = Ds.Tables(0).Rows(0)(1)
Max1 = Ds.Tables(0).Rows(0)(1)
For i As Integer = 0 To Ds.Tables(0).Rows.Count - 1
series(i) = New Series() With { _
.Name = Left(Ds.Tables(0).Rows(i)(0).ToString(), 2), _
.Data = New Data(New Object() {Ds.Tables(0).Rows(i)(1)})}
If Min1 > Ds.Tables(0).Rows(i)(1) Then
Min1 = Ds.Tables(0).Rows(i)(1)
End If
If Max1 < Ds.Tables(0).Rows(i)(1) Then
Max1 = Ds.Tables(0).Rows(i)(1)
End If
Next
chart1.SetYAxis(New YAxis With {.GridLineWidth = 0, .Title = New YAxisTitle With {.Text = "Percentage"}, .Min = Min1 - 2, .Max = Max1 + 2})
chart1.SetTooltip(New Tooltip() With {.Formatter = "function() { return '<b>'+ this.series.name + ': </b>'+ this.y +' %'; }"})
chart1.SetSeries(series)
ltChart.Text = chart1.ToHtmlString()
I am trying to bind a grouped linq statement to a asp.net listview. Problem is when the result is been returned to my list view my result look like this.
System.Linq.Enumerable+WhereEnumerableIterator1[TransactionDetail] 20.5 System.Linq.Enumerable+WhereEnumerableIterator1[TransactionDetail] 7.3
My code is nothing special
List<TransactionDetail> transactions = new List<TransactionDetail>();
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 2, TransactionID = 1, IsPurchase = true });
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 2.2, TransactionID = 2, IsPurchase = true });
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 2.9, TransactionID = 3, IsPurchase = false });
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 4, TransactionID = 4, IsPurchase = true });
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 2.2, TransactionID = 5, IsPurchase = false });
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 5, TransactionID = 6, IsPurchase = true });
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 5, TransactionID = 7, IsPurchase = true });
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 2.3, TransactionID = 8, IsPurchase = true });
transactions.Add(new TransactionDetail { PurchaseDate = DateTime.Now, TransactionAmount = 2.2, TransactionID = 9, IsPurchase = false });
var grouped = from t in transactions
group t by t.IsPurchase into g
select new {
AddedPurchase = g.Where(s=>s.IsPurchase),
Balance = g.Sum(s=>s.TransactionAmount)
};
lstTransactions.DataSource = grouped;
lstTransactions.DataBind();
My listview looks somthing like this
<ItemTemplate>
<span> <%# Eval("AddedPurchase")%></span><span> <%# Eval("Balance")%></span>
</ItemTemplate>
Why am I seeing the System.Linq.Enumerable+WhereEnumerableIterator1[WebUI.TransactionDetail] 20.5 with my returned result. I am only interested in AddedPurchase and Balance
I cant offer a good explanation as to why this is happening but you might like to try the following two fixes:
Add ".ToList()" to the end of your LINQ query. This should stop you seeing the "WhereEnumerableIterator1" type description from popping up.
Add a further LINQ query which can select a new list of ListItems from your grouping:
lstTransactions.Items.AddRange(
grouped.Select(x => new ListItem(x.AddedPurchase, x.Balance)
)
EDIT:
The problem in fact lies with your second LINQ query, where you select out the new anonymous type into the variable grouped:
AddedPurchase = g.Where(s=>s.IsPurchase)
Added purchase will have the value of a Where() iterator. Im not sure what the purpose of the "AddedPurchase" variable is but if you for example wanted to signify a purchse had been made, then you could do:
AddedPurchase = g.Where(s=>s.IsPurchase).Count() > 0