The list of doubles SC is of same size for all of CTable.
I would like add SC grouped by CTable.Ch. The result should be a List of sums. Is there an operator/customization for that?
Public Class SCRow
Public L As String
Public Ch As String
Public SC As List(Of Double)
End Class
Dim CTable AS New List(Of SCRow)
Dim AggrC =
From C In CTable
Group C By Key = C.Ch
Into Group
Select New With
{
.Ch= Key,
.SumSC = Group.Sum(Function(x) ???)
}
Example:
CTable.Add(New SCRow With {.L = "L1", .Ch = "Ch1", .SC = New List(Of Double)(New Double() {1.0, 2.0})})
CTable.Add(New SCRow With {.L = "L1", .Ch = "Ch2", .SC = New List(Of Double)(New Double() {3.0, 4.0})})
CTable.Add(New SCRow With {.L = "L2", .Ch = "Ch1", .SC = New List(Of Double)(New Double() {5.0, 6.0})})
Output:
Ch1 {6=1+5, 8=2+6}
Ch2 {3, 4}
It can be done using Aggregate extension method along with Zip method. I have written the code in C#. Please translate it to VB.Net. Hope it will help.
Aggregate: Performs a specified operation to each element in a collection, while carrying the result forward.
Zip: The Zip extension method acts upon two collections. It processes each element in two series together.
public class SCRow
{
public string L { get; set; }
public string CH { get; set; }
public List<double> SC { get; set; }
}
class Program
{
static void Main(string[] args)
{
var CTable = new List<SCRow>{
new SCRow { L = "L1", CH = "Ch1", SC = new List<double> { 1.0, 2.0}},
new SCRow { L = "L1", CH = "Ch2", SC = new List<double> { 3.0, 4.0}},
new SCRow { L = "L2", CH = "Ch1", SC = new List<double> { 5.0, 6.0}},
};
var result = CTable.GroupBy(c => c.CH)
.Select(x => new
{
Value = x.Aggregate((curr, next) => new SCRow
{
CH = x.Key,
SC = curr.SC.Zip(next.SC, (n1, n2) => n1 + n2).ToList()
})
})
.Select(y => new {
CH = y.Value.CH,
ScSum = y.Value.SC
}).ToList();
}
}
Related
Ok so I have been making a simple code editor in vb.net for go.. (for personal uses)
I tried this code -
Dim tokens As String = "(break|default|func|interface|select|case|defer|go|map|struct|chan|else|goto|package|switch|const|fallthrough|if|range|type|continue|for|import|return|var)"
Dim rex As New Regex(tokens)
Dim mc As MatchCollection = rex.Matches(TextBox2.Text)
Dim StartCursorPosition As Integer = TextBox2.SelectionStart
For Each m As Match In mc
Dim startIndex As Integer = m.Index
Dim StopIndex As Integer = m.Length
TextBox2.[Select](startIndex, StopIndex)
TextBox2.SelectionColor = Color.FromArgb(0, 122, 204)
TextBox2.SelectionStart = StartCursorPosition
TextBox2.SelectionColor = Color.RebeccaPurple
Next
but I couldn't add something like print statements say I want a fmt.Println("Hello World"), that is not possible, anyone help me?
I want a simple result that will do proper syntax without glitching text colors like this current code does.
Here's a code showing how to update highlighting with strings and numbers.
You would need to tweak it further to support syntax like comments, etc.
private Regex BuildExpression()
{
string[] exprs = {
"(break|default|func|interface|select|case|defer|go|map|struct|chan|else|goto|package|switch|const|fallthrough|if|range|type|continue|for|import|return|var)",
#"([0-9]+\.[0-9]*(e|E)(\+|\-)?[0-9]+)|([0-9]+\.[0-9]*)|([0-9]+)",
"(\"\")|\"((((\\\\\")|(\"\")|[^\"])*\")|(((\\\\\")|(\"\")|[^\"])*))"
};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < exprs.Length; i++)
{
string expr = exprs[i];
if ((expr != null) && (expr != string.Empty))
sb.Append(string.Format("(?<{0}>{1})", "_" + i.ToString(), expr) + "|");
}
if (sb.Length > 0)
sb.Remove(sb.Length - 1, 1);
RegexOptions options = RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase;
return new Regex(sb.ToString(), options);
}
private void HighlightSyntax()
{
var colors = new Dictionary<int, Color>();
var expression = BuildExpression();
Color[] clrs = { Color.Teal, Color.Red, Color.Blue };
int[] intarray = expression.GetGroupNumbers();
foreach (int i in intarray)
{
var name = expression.GroupNameFromNumber(i);
if ((name != null) && (name.Length > 0) && (name[0] == '_'))
{
var idx = int.Parse(name.Substring(1));
if (idx < clrs.Length)
colors.Add(i, clrs[idx]);
}
}
foreach (Match match in expression.Matches(richTextBox1.Text))
{
int index = match.Index;
int length = match.Length;
richTextBox1.Select(index, length);
for (int i = 0; i < match.Groups.Count; i++)
{
if (match.Groups[i].Success)
{
if (colors.ContainsKey(i))
{
richTextBox1.SelectionColor = colors[i];
break;
}
}
}
}
}
What we found during development of our Code Editor libraries, is that the regular expression-based parsers are hard to adapt to fully support advanced syntax like contextual keywords (LINQ) or interpolated strings.
You might find a bit more information here:
https://www.alternetsoft.com/blog/code-parsing-explained
The most accurate syntax highlighting for VB.NET can be implemented using Microsoft.CodeAnalysis API, it's the same API used internally by Visual Studio text editor.
Below is sample code showing how to get classified spans for VB.NET code (every span contains start/end position within the text and classification type, i.e. keyword, string, etc.). These spans then can be used to highlight text inside a textbox.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Text;
public class VBClassifier
{
private Workspace workspace;
private static string FileContent = #"
Public Sub Run()
Dim test as TestClass = new TestClass()
End Sub";
public void Classify()
{
var project = InitProject();
var doc = AddDocument(project, "file1.vb", FileContent);
var spans = Classify(doc);
}
protected IEnumerable<ClassifiedSpan> Classify(Document document)
{
var text = document.GetTextAsync().Result;
var span = new TextSpan(0, text.Length);
return Classifier.GetClassifiedSpansAsync(document, span).Result;
}
protected Document AddDocument(Project project, string fileName, string code)
{
var documentId = DocumentId.CreateNewId(project.Id, fileName);
ApplySolutionChanges(s => s.AddDocument(documentId, fileName, code, filePath: fileName));
return workspace.CurrentSolution.GetDocument(documentId);
}
protected virtual void ApplySolutionChanges(Func<Solution, Solution> action)
{
var solution = workspace.CurrentSolution;
solution = action(solution);
workspace.TryApplyChanges(solution);
}
protected MefHostServices GetRoslynCompositionHost()
{
IEnumerable<Assembly> assemblies = MefHostServices.DefaultAssemblies;
var compositionHost = MefHostServices.Create(assemblies);
return compositionHost;
}
protected Project CreateDefaultProject()
{
var solution = workspace.CurrentSolution;
var projectId = ProjectId.CreateNewId();
var projectName = "VBTest";
ProjectInfo projectInfo = ProjectInfo.Create(
projectId,
VersionStamp.Default,
projectName,
projectName,
LanguageNames.VisualBasic,
filePath: null);
ApplySolutionChanges(s => s.AddProject(projectInfo));
return workspace.CurrentSolution.Projects.FirstOrDefault();
}
protected Project InitProject()
{
var host = GetRoslynCompositionHost();
workspace = new AdhocWorkspace(host);
return CreateDefaultProject();
}
}
Update:
Here's a Visual Studio project demonstrating both approaches:
https://drive.google.com/file/d/1LLuzy7yDFAE-v40I7EswECYQSthxheEf/view?usp=sharing
how can i add memorycache in this method ?
this is a section of my code that i want to set memory cache on it.
public IActionResult Index(int pageId = 1, string filter = "",
int startPrice = 0, int endPrice = 0, string getType = "", string orderByType = "date",
List<int> selectedGroups = null, List<int> selectedBrand = null, List<int> selectedTags = null
, List<int> selectedsize = null , string Discount = "")
{
ViewBag.selectedGroups = selectedGroups;
ViewBag.selectedTags = selectedTags;
ViewBag.selectedsize = selectedsize;
ViewBag.Discount = Discount;
ViewBag.getType = getType;
ViewBag.Groups = _productService.GetAllGroup();
ViewBag.Tags = _productService.GetTags().Where(c => c.ActiveRow).ToList();
ViewBag.size = _productService.GetSizes().ToList();
ViewBag.pageId = pageId;
return View(_productService.GetProducttype(pageId, filter, startPrice, endPrice, getType, orderByType, selectedGroups, selectedBrand, 24, selectedTags, selectedsize, Discount));
}
private readonly IMemoryCache _memoryCache;
public Constructor (IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public IActionResult Index(int pageId = 1, string filter = "",
int startPrice = 0, int endPrice = 0, string getType = "", string orderByType = "date",
List<int> selectedGroups = null, List<int> selectedBrand = null, List<int> selectedTags = null
, List<int> selectedsize = null , string Discount = "")
{
ViewBag.selectedGroups = selectedGroups;
ViewBag.selectedTags = selectedTags;
ViewBag.selectedsize = selectedsize;
ViewBag.Discount = Discount;
ViewBag.getType = getType;
var groups = new List<Group>();
if (_memoryCache.TryGetValue("groups", out groups)
{
ViewBag.Groups = groups;
}
else
{
groups = _productService.GetAllGroup();
_memoryCache.Set("groups", groups);
ViewBag.Groups = groups;
}
var tags = new List<Tag>();
if (_memoryCache.TryGetValue("tags", out tags)
{
ViewBag.Tags = tags;
}
else
{
tags = _productService.GetTags().Where(c => c.ActiveRow).ToList();
_memoryCache.Set("tags", tags);
ViewBag.Tags = tags;
}
var sizes = new List<Size>();
if (_memoryCache.TryGetValue("sizes", out sizes)
{
ViewBag.size = sizes;
}
else
{
sizes = _productService.GetSizes().ToList();
_memoryCache.Set("sizes", sizes);
ViewBag.size = sizes;
}
var pageId = null;
if (_memoryCache.TryGetValue("pageId", out pageId))
{
ViewBag.pageId = pageId;
}
else
{
_memoryCache.Set("pageId", pageId);
ViewBag.pageId = pageId;
}
return View(_productService.GetProducttype(pageId, filter, startPrice, endPrice, getType, orderByType, selectedGroups, selectedBrand, 24, selectedTags, selectedsize, Discount));
}
I know how to build a simple lambda like x => x > 5:
int[] nbs = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> result1 = nbs.Where(x => x > 5);
ParameterExpression parameter = Expression.Parameter(typeof(int), "x");
ConstantExpression constant = Expression.Constant(5);
BinaryExpression expressionBody = Expression.GreaterThan(parameter, constant);
Expression<Func<int, bool>> expression = Expression.Lambda<Func<int, bool>>(expressionBody, parameter);
IEnumerable<int> result2 = nbs.Where(expression.Compile());
But, how do I create a more complex lambda like this p=>p.FindAttribute("Gender")?.Value == "Female" in the same style as above?
public class Person
{
public bool POI { get; set; } = false;
public string Name { get; set; }
public List<Car> Cars { get; set; }
public List<Attribute> Attributes { get; set; }
public bool PersonOfInterest()
{
return POI;
}
public Attribute FindAttribute(string name)
{
return Attributes.FirstOrDefault(a => a.Name == name);
}
}
public class Attribute
{
public string Name { get; set; }
public string Value { get; set; }
public Attribute(string name, string value) { Name = name; Value = value; }
}
public class Car
{
public string Make { get; set; }
public int Horsepowers { get; set; }
public string Fuel { get; set; }
}
Person p1 = new Person();
p1.Name = "Thom";
p1.POI = true;
p1.Attributes = new List<Attribute>() {new Attribute("Length", "Tall"), new Attribute("Hair", "Long hair")};
p1.Cars = new List<Car>()
{
new Car(){Horsepowers = 100, Make = "Toyota", Fuel = "Diesel"},
new Car(){Horsepowers = 200, Make = "Fiat", Fuel = "Diesel"},
new Car(){Horsepowers = 300, Make = "Audi", Fuel = "Diesel"},
new Car(){Horsepowers = 150, Make = "Ferrari", Fuel = "Petrol"}
};
Person p2 = new Person();
p2.POI = false;
p2.Attributes = new List<Attribute>() { new Attribute("Nationality", "English"), new Attribute("Gender", "Female") };
p2.Name = "Sophie";
p2.Cars = new List<Car>()
{
new Car(){Horsepowers = 500, Make = "McLaren", Fuel = "Diesel"},
new Car(){Horsepowers = 200, Make = "Volvo", Fuel = "Diesel"},
new Car(){Horsepowers = 300, Make = "Audi", Fuel = "Diesel"},
new Car(){Horsepowers = 400, Make = "Ferrari", Fuel = "Diesel"}
};
IEnumerable<Person> res = persons.Where(p=>p.FindAttribute("Gender")?.Value == "Female");
Of course I could always create a new method on Person like:
public bool HasAttributeWithValue(string name, string value)
{
return FindAttribute(name)?.Value == value;
}
But it's still of interest to me if it's possible to construct the complex lambda dynamically!
This piece of code does the job.
ParameterExpression parameter = Expression.Parameter(typeof(Person), "p");
ConstantExpression my_null_object = Expression.Constant(null);
ConstantExpression gender = Expression.Constant("Gender");
MethodCallExpression methodcall = Expression.Call(parameter, typeof(Person).GetMethod("FindAttribute"), gender);
BinaryExpression is_null = Expression.Equal(methodcall, my_null_object);
ConstantExpression constant = Expression.Constant("Female");
MemberExpression member = Expression.Property(methodcall, typeof(Attribute).GetProperty("Value"));
BinaryExpression expressionBody = Expression.Equal(member, constant);
BinaryExpression cond = Expression.AndAlso(Expression.IsFalse(is_null), expressionBody);
Maybe clearer this way
ParameterExpression parameter = Expression.Parameter(typeof(Person), "p");
ConstantExpression my_null_object = Expression.Constant(null);
MethodCallExpression methodcall = Expression.Call(parameter, typeof(Person).GetMethod("FindAttribute"), Expression.Constant("Gender"));
BinaryExpression cond = Expression.AndAlso(
Expression.IsFalse(Expression.Equal(methodcall, my_null_object)),
Expression.Equal(
Expression.Property(methodcall, typeof(Attribute).GetProperty("Value")),
Expression.Constant("Female")
)
);
Null-conditional operator is a language feature. It can be converted to this code:
var attribute = p.FindAttribute("Gender");
return attribute == null ? false : attribute.Value == "Female";
To build an expression tree you can use Expression.Block:
var p = Expression.Parameter(typeof(Person), "p");
var findAttribute = Expression.Call(p,
typeof(Person).GetMethod(nameof(Person.FindAttribute)),
Expression.Constant("Gender"));
var attribute = Expression.Parameter(typeof(Attribute), "attribute");
var body = Expression.Block(
new[] {attribute}, // local variables
new Expression[]
{
Expression.Assign(attribute, findAttribute),
Expression.Condition(
Expression.Equal(attribute, Expression.Constant(null)),
Expression.Constant(false),
Expression.Equal(
Expression.PropertyOrField(attribute, "Value"),
Expression.Constant("Female")))
}
);
var lambda = Expression.Lambda<Func<Person, bool>>(body, p);
I would like to know the best way to compare 2 complex objects to know if they are equal by value, ie, their properties are the same? I tried the serialize method and not sure why they are not equal by value
Dim stream As New MemoryStream()
Dim bstream As New MemoryStream()
Dim clientOne As Jewellery.ClientInfo = New Jewellery.ClientInfo(New Jewellery.Company("a", "", "", "b", "", "e"), New Jewellery.Customer("a", "b", "c", "d", "", "", "", "f"))
Dim clientTwo As Jewellery.ClientInfo = New Jewellery.ClientInfo(New Jewellery.Company("a", "", "", "b", "", "e"), New Jewellery.Customer("a", "b", "c", "d", "", "", "", "f"))
formatter.Serialize(stream, clientOne)
formatter.Serialize(bstream, clientTwo)
Dim streamOneBytes As Byte() = stream.ToArray()
Dim streamTwoBytes As Byte() = bstream.ToArray()
Dim streamToCompareBytes As Byte() = streamToCompare.ToArray()
Dim i As Int16 = 0
Dim flag As Boolean
If streamOneBytes.Length <> streamTwoBytes.Length Then
MsgBox("False")
flag = False
Else
While i < streamOneBytes.Count
If streamOneBytes(i) <> streamTwoBytes(i) Then
flag = "False"
Else : flag = "True"
End If
i = i + 1
End While
End If
As you see in the above code, when I initialize 2 objects of the same type and compare, it works correctly. But when I add one object to say a List and then retrieve and compare to an object of similar type, it fails saying the binary width are different for both. Any advice? Thanks
public class IntegerPropertyEqualityCompare : IEqualityComparer<Main>
{
#region IEqualityComparer<Main> Members
public bool Equals( Main x, Main y )
{
return x.IntegerProperty == y.IntegerProperty;
}
public int GetHashCode( Main obj )
{
return obj.IntegerProperty.GetHashCode() ^ obj.StringProperty.GetHashCode();
}
#endregion
}
public class StringPropertyEqualityCompare : IEqualityComparer<Main>
{
#region IEqualityComparer<Main> Members
public bool Equals( Main x, Main y )
{
return x.StringProperty == y.StringProperty;
}
public int GetHashCode( Main obj )
{
return obj.IntegerProperty.GetHashCode() ^ obj.StringProperty.GetHashCode();
}
#endregion
}
public class AllPropertiesEqualityCompare : IEqualityComparer<Main>
{
#region IEqualityComparer<Main> Members
public bool Equals( Main x, Main y )
{
return ( x.IntegerProperty == y.IntegerProperty ) && ( x.StringProperty == y.StringProperty );
}
public int GetHashCode( Main obj )
{
return obj.IntegerProperty.GetHashCode() ^ obj.StringProperty.GetHashCode();
}
#endregion
}
public abstract class Main
{
public int IntegerProperty { get; set; }
public string StringProperty { get; set; }
public bool Equals( IEqualityComparer<Main> comparer, Main other )
{
return comparer.Equals( this, other );
}
}
public class ConcreteA : Main
{ }
public class ConcreteB : Main
{ }
class TemporaryTest
{
public static void Run()
{
var a = new ConcreteA();
a.IntegerProperty = 1;
a.StringProperty = "some";
var b = new ConcreteB();
b.IntegerProperty = 1;
a.StringProperty = "other";
Console.WriteLine( a.Equals( new IntegerPropertyEqualityCompare(), b ) );
Console.WriteLine( a.Equals( new StringPropertyEqualityCompare(), b ) );
Console.WriteLine( a.Equals( new AllPropertiesEqualityCompare(), b ) );
}
}
Maybe then somthing like this?
I'm not sure that I understand what you want to do.
So I go with IComparable<T>.
I am new to MVC3 Razor. How can I show data table data in webgrid ?
Below is what I have tried...
My Home Controller
Public Function List() As ActionResult
Dim dt1 As New DataTable
dt1.Columns.Add("Eno", GetType(Int32))
dt1.Columns.Add("Ename", GetType([String]))
dt1.Columns.Add("Salary", GetType([Double]))
dt1.Columns.Add("Deptno", GetType(Int32))
' Loading data into dt1, dt2:
Dim o1 As Object() = {1, "a", 50000.5, 10}
Dim o2 As Object() = {2, "b", 4000.5, 20}
Dim o3 As Object() = {3, "c", 10000.5, 10}
dt1.Rows.Add(o1)
dt1.Rows.Add(o2)
dt1.Rows.Add(o3)
dt1.AsEnumerable()
Dim columns = dt1.Columns.Cast(Of DataColumn)()
Dim wgrid As Web.Helpers.WebGrid
wgrid = New Web.Helpers.WebGrid(source:=columns, defaultSort:="Eno", rowsPerPage:=2)
Return View(wgrid)
End Function
My View
#ModelType System.Web.Helpers.WebGrid
<h1>Emp Details</h1>
<div id="grid">
#Model.GetHtml(tableStyle:="grid", headerStyle:="head", alternatingRowStyle:="alt", columns:={Model.Column("Eno")})
</div>
My Problem
I get an error message as "Column "Eno" does not exist."
what i need is i want to show the data in the webgrid as
---------------------------------
Eno Ename Salary Deptno
---------------------------------
1 a 50000.5 10
2 b 4000.5 20
3 c 10000.5 10
---------------------------------
please help me out on this.
You should return a List as your model to your view...
To start with you should have a class like the one shown below...
public class SomeDetails
{
public string Eno { get; set; }
public string Ename { get; set; }
public string Salary { get; set; }
public string Deptno { get; set; }
}
and your function should return a list of this class.
and then your view can have Model defined as a List of this class and then you can use your webgrid's code
i got the solution in another way
Dim dt1 As New DataTable
dt1.Columns.Add("Eno", GetType(Int32))
dt1.Columns.Add("Ename", GetType([String]))
dt1.Columns.Add("Salary", GetType([Double]))
dt1.Columns.Add("Deptno", GetType(Int32))
Dim o1 As Object() = {1, "a", 50000.5, 10}
Dim o2 As Object() = {2, "b", 4000.5, 20}
Dim o3 As Object() = {3, "c", 10000.5, 10}
dt1.Rows.Add(o1)
dt1.Rows.Add(o2)
dt1.Rows.Add(o3)
Dim skip As Integer = If(page.HasValue, page.Value - 1, 0)
Dim data = From row In dt1.AsEnumerable() Select New With {.value = row("intDepartmentID").ToString, .display = row("vchDepartment").ToString}
Dim grid = New Helpers.WebGrid(data, rowsPerPage:=10)
Dim htmlString = grid.GetHtml(tableStyle:="webgrid", htmlAttributes:=New With {.id = "DataTable"}, headerStyle:="webgrid-header", alternatingRowStyle:="webgrid-alternating-row", footerStyle:="webgrid-footer", selectedRowStyle:="webgrid-selected-row", rowStyle:="webgrid-row-style", columns:=grid.Columns(grid.Column("display", "Eno"), grid.Column("value", "Ename")))
Return Json(New With {.Data = htmlString.ToHtmlString(), .count = data.Count()}, JsonRequestBehavior.AllowGet)
and view
<div class="tablegridpanel">
<div id="div1">
</div>
</div>
<script type="text/javascript">
/* On pageload web grid is loaded */
$(document).ready(function () {
alert("hii");
PopulateGrid();
});
function PopulateGrid() {
$.getJSON("/Home/webGrid", null, function (d) {
if (d.count > 0) {
$("#DataTable").remove();
$("#div1").append(d.Data);
}
else {
$('#div1').hide();enter code here
}
var footer = createFooter(d.Count);
$("#DataTable tfoot a").live("click", function (e) {
e.preventDefault();
var data = {`enter code here`
page: $(this).text()
};
$.getJSON("/Home/webGrid", { page: data.page }, function (html) {
if (html.count > 0) {
$("#DataTable").remove();
$("#div1").append(html.Data);
// $('#DataTable thead').after(footer);
}
else {
$('#div1').hide();
}
});
});
});
}
function createFooter(d) {
var rowsPerPage = 5;
var footer = "<tfoot>";
for (var i = 1; i < (d + 1); i++) {
footer = footer + "<a href=#>" + i + "</a> ";
}
footer = footer + "</tfoot>";
// $("#DataTable thead").after(footer);
return footer;
}
</script>