Change List<Object> into List<List<int>> using LINQ - arrays

I have an application using the following model:
namespace myapp.Models.Types
{
public class PressureRowT
{
public System.DateTime Timestamp { get; set; }
public int P1{ get; set; }
public int P2{ get; set; }
public int P3{ get; set; }
public int P4{ get; set; }
public int P5{ get; set; }
}
}
I have a List< PressureRowT > with approximately 5000 elements, generated by parsing files. I need to plot the pressure by passing the data to chart.js for data viewing. For that, I would need a JSON array like:
[Timestamp: [date1, date2, date3... daten], P1: [val1, val2, val3, ..., valn], P2: [val1, val2, val3, ..., valn] ... P5: [val1, val2, val3, ..., valn]]
What would be the most efficient way of "inverting" the structure ?
Thank you in advance.

Assuming right now you have a list of PressureRowT and you want an object PressureRowT with lists within it, you can use something like
var Timestamps = pressureRowTList.Select(pressureRowT => pressureRowT.TimeStamp).ToList();
for each of the fields and assign them all to one object.

The most efficient way would be to re-write your parsing code to build the correct structures as the files are read.
Barring that, the best thing to do is not use LINQ, but simply build the Lists needed. A for loop is more efficient than a foreach when processing a List:
var src = new List<PressureRowT>();
var srccount = src.Count;
var PR_TS = new List<DateTime>(srccount);
var PR_P1 = new List<int>(srccount);
var PR_P2 = new List<int>(srccount);
var PR_P3 = new List<int>(srccount);
var PR_P4 = new List<int>(srccount);
var PR_P5 = new List<int>(srccount);
for (int j1 = 0; j1 < srccount; ++j1) {
PR_TS.Add(src[j1].Timestamp);
PR_P1.Add(src[j1].P1);
PR_P2.Add(src[j1].P2);
PR_P3.Add(src[j1].P3);
PR_P4.Add(src[j1].P4);
PR_P5.Add(src[j1].P5);
}
var ans = new { Timestamp = PR_TS, P1 = PR_P1, P2 = PR_P2, P3 = PR_P3, P4 = PR_P4, P5 = PR_P5 };

I might use Aggregate to build up the result object:
IEnumerable<PressureRowT> values;
var resultSeed = new {
Timestamp = new List<DateTime>(),
P1 = new List<int>(),
P2 = new List<int>(),
P3 = new List<int>(),
P4 = new List<int>(),
P5 = new List<int>(),
};
return values.Aggregate(
resultSeed,
(result, value) => {
result.Timestamp.Add(value.Timestamp);
result.P1.Add(value.P1);
result.P2.Add(value.P2);
result.P3.Add(value.P3);
result.P4.Add(value.P4);
result.P5.Add(value.P5);
return result;
});

Related

Customizing the creation of anonymous sequences in AutoFixture

Using anonymous sequences, I can create sequences of objects when I don't care so much about how many, or what type of sequence it is:
public class Foo { public string Bar { get; set; } }
var fixture = new Fixture();
var foos = fixture.CreateMany<Foo>();
Is there some way I can customize the creation of such sequences, and e.g. set a property on each item in the collection, in a way that considers the entire collection at once, and not just one item at a time?
For example, is there a way to achieve the following?
public interface ISortable
{
int SortOrder { get; set; }
}
public class Foo : ISortable
{
public string Bar { get; set; }
public int SortOrder { get; set; }
}
var fixture = new Fixture();
// TODO: Customize the fixture here
var foos = fixture.CreateMany<Foo>();
// foos now have sort-order set to e.g. a multiple of their index
// in the list, so if three items, they have sort order 0, 10, 20.
It's been a while since I handed over control of AutoFixture, so my information could be out of date, but I don't think there's any feature like that. What I usually do in cases like that is that use normal code to configure what AutoFixture generates. In this particular case, you can use a zip to achieve the desired result; prototype:
[Fact]
public void SetSortOrderOnFoos()
{
var fixture = new Fixture();
var foos = fixture
.CreateMany<Foo>()
.Zip(
Enumerable.Range(0, fixture.RepeatCount),
(f, i) => { f.SortOrder = i * 10; return f; });
Assert.Equal(3, foos.Count());
Assert.Equal( 0, foos.ElementAt(0).SortOrder);
Assert.Equal(10, foos.ElementAt(1).SortOrder);
Assert.Equal(20, foos.ElementAt(2).SortOrder);
}
This test isn't robust, but I hope it communicates the core idea.

Reference a scalar property from a string value

I have a combobox that contains a list of scalar properties of an entity. I need to do a search on the property specified by the user in the combobox.
How do I reference the property when I have it as a string?
Something similar to DBSet<> for entity.
Example:
if (order.Firstname != null && order.Firstname.ToLower().Contains(textBoxSearch.Text.ToLower()))
In the above example, I need to replace Firstname with Surname or any other property, at runtime, depending on what the user selected.
You can always use reflection, for your case you'll need something along these lines:
static void Main(string[] args)
{
var entity = new Entity {
Height = 172,
FirstName = "Foo",
Birthday = new DateTime(1, 1, 1995)
};
var firstName = GetEntityProperty<string>(entity, "FirstName");
}
public static T GetEntityProperty<T>(object entity, string propertyName)
{
var type = entity.GetType();
var property = type.GetProperty(propertyName);
return (T)property.GetValue(entity);
}
Provided solution works, but it is not strongly-typed, so it is sensible to property renaming. A strongly-typed approach can be used, but it requires some setup. However, part of the setup is so generic that it can be reused:
public class Order
{
public String OrderNo { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Misc { get; set; }
}
// clearly define properties that allow search
public enum OrderSearchableProp
{
OrderNo = 1,
FirstName = 2,
LastName = 3
}
class Program
{
// strongly-type requires an explicit mapping between property and its expression within the order object
static Dictionary<OrderSearchableProp, Expression<Func<Order, String>>> OrderSearchableMap = new Dictionary<OrderSearchableProp, Expression<Func<Order, string>>>()
{
{ OrderSearchableProp.OrderNo, o => o.OrderNo },
{ OrderSearchableProp.FirstName, o => o.FirstName },
{ OrderSearchableProp.LastName, o => o.LastName },
};
// this gets a PropertyInfo based from an Expression. It should be placed into a generic utility class
// credit goes to Daniel - http://stackoverflow.com/a/17116267/2780791
public static PropertyInfo GetPropertyFromExpression<T, TProp>(Expression<Func<T, TProp>> GetPropertyLambda)
{
MemberExpression Exp = null;
//this line is necessary, because sometimes the expression comes in as Convert(originalexpression)
if (GetPropertyLambda.Body is UnaryExpression)
{
var UnExp = (UnaryExpression)GetPropertyLambda.Body;
if (UnExp.Operand is MemberExpression)
{
Exp = (MemberExpression)UnExp.Operand;
}
else
throw new ArgumentException();
}
else if (GetPropertyLambda.Body is MemberExpression)
{
Exp = (MemberExpression)GetPropertyLambda.Body;
}
else
{
throw new ArgumentException();
}
return (PropertyInfo)Exp.Member;
}
public static IList<Order> getFilteredOrders(int propFilterValue, IList<Order> orders, String needle)
{
var filterValue = (OrderSearchableProp)propFilterValue;
var filterProp = OrderSearchableMap[filterValue];
var lowNeedle = needle?.ToLower() ?? String.Empty;
return orders.Where(o =>
{
var propInfo = GetPropertyFromExpression<Order, String>(filterProp);
var propValue = (String) propInfo.GetValue(o) ?? String.Empty;
return propValue.ToLower().Contains(lowNeedle);
}).ToList();
}
static void Main(string[] args)
{
// can be used to populate the combo items
// otherwise, not used in this example
OrderSearchableProp[] enumValues = (OrderSearchableProp[])Enum.GetValues(typeof(OrderSearchableProp));
// test orders
var orderList = new List<Order>()
{
new Order() { OrderNo = "1234ABC", FirstName = "George", LastName = "Taylor", Misc = "Extra information"},
new Order() { OrderNo = "AB10", FirstName = "Anonymous", LastName = "X", Misc = "No comment"}
};
// test OrderNo search
var searchProp = (int) OrderSearchableProp.OrderNo;
var foundOrders = getFilteredOrders(searchProp, orderList, "ABC");
// test FirstName search
searchProp = (int)OrderSearchableProp.FirstName;
foundOrders = getFilteredOrders(searchProp, orderList, "a");
// test LastName search with empty string
searchProp = (int)OrderSearchableProp.LastName;
foundOrders = getFilteredOrders(searchProp, orderList, "");
// empty return
searchProp = (int)OrderSearchableProp.OrderNo;
foundOrders = getFilteredOrders(searchProp, orderList, null);
}
}

Map a column with string representing a list to a List<> object using Dapper

I have the following model:
public class Model {
public string Name { get; set; }
public List<int> Numbers { get; set; }
}
And an SQL query that returns the following dataset containing two nvarchar columns:
Name
Numbers
foo
1,2,3,4
bar
4,17
Is there a simple way to auto-assign the results of the query to a List<Model> using Dapper?
I know I could use multi-mapping and make the splitting myself in C# code, but I would rather get a simpler solution.
I'm not sure if you can call this "simpler", but something like this is an option:
public class Result
{
public string Name { get; set; }
public List<int> Numbers { get; set; }
}
public class DapperTests
{
[Test]
public void Test()
{
var conn = new SqlConnection(#"Data Source=.\sqlexpress; Integrated Security=true; Initial Catalog=mydb");
conn.Open();
var result = conn.Query<string, string, Result>(
"select Name = 'Foo', Numbers = '1,2,3' union all select Name = 'Bar', Numbers = '4,5,6'", (a, b) => new Result
{
Name = a,
Numbers = b.Split(',').Select(Int32.Parse).ToList()
}, splitOn: "*").ToList();
Assert.That(result.Count, Is.EqualTo(2));
Assert.That(result.FirstOrDefault(x => x.Name == "Foo").Numbers.Count, Is.GreaterThan(0));
Assert.That(result.FirstOrDefault(x => x.Name == "Bar").Numbers.Count, Is.GreaterThan(0));
}
}
An alternative option with multimapping... pretty ugly
public class Result
{
public string Name { get; set; }
public List<int> NumberList { get; set; }
public string Numbers { set { NumberList = value.Split(',').Select(Int32.Parse).ToList(); } }
}
public class DapperTests
{
[Test]
public void Test()
{
var conn = new SqlConnection(#"Data Source=.\sqlexpress; Integrated Security=true; Initial Catalog=mydb");
conn.Open();
var sql = #"
select Name = 'Foo', Numbers = '1,2,3';
select Name = 'Bar', Numbers = '4,5,6';";
var expectedResults = 2;
var results = new List<Result>();
using (var multi = conn.QueryMultiple(sql))
{
for (int i = 0; i < expectedResults; i++)
{
results.Add(multi.Read<Result>().Single());
}
}
Assert.That(results.Count, Is.EqualTo(2));
Assert.That(results.FirstOrDefault(x => x.Name == "Foo").NumberList.Count, Is.GreaterThan(0));
Assert.That(results.FirstOrDefault(x => x.Name == "Bar").NumberList.Count, Is.GreaterThan(0));
}
}

Why doesn't Autofixture Likeness behave like I'd expect for one of these two tests?

Given these classes:
public class DrumAndBassBand
{
public Drums Drum { get; set; }
public Bass Bass { get; set; }
}
public class Instrument
{
public string Name { get; set; }
public int SerialNumber { get; set; }
}
public class Drums : Instrument { }
public class Bass : Instrument { }
Why does this test pass...
[Fact]
public void DrumAndBassBand_Equality_Behaves_As_Expected_Version_One()
{
// arrange
var template = new Fixture().Create<DrumAndBassBand>();
// act
var createdBand = new DrumAndBassBand {Drum = template.Drum, Bass = template.Bass};
// assert
var createdLikeness = createdBand.AsSource().OfLikeness<DrumAndBassBand>()
.Without(x => x.Bass)
.CreateProxy();
createdLikeness.Drum = createdBand.Drum;
Assert.True(createdLikeness.Equals(template));
var templateLikeness = template.AsSource().OfLikeness<DrumAndBassBand>()
.Without(x => x.Bass)
.CreateProxy();
templateLikeness.Drum = template.Drum;
Assert.True(templateLikeness.Equals(createdBand));
}
...and this one fail? (the difference is the DrumAndBaseBand instantiation)
[Fact]
public void DrumAndBassBand_Equality_Behaves_As_Expected_Version_Two()
{
// arrange
var template = new Fixture().Create<DrumAndBassBand>();
// act
var createdBand =
new DrumAndBassBand
{
Drum = new Drums { Name = template.Drum.Name, SerialNumber = template.Drum.SerialNumber },
Bass = new Bass { Name = template.Bass.Name, SerialNumber = template.Bass.SerialNumber }
};
// assert
var createdLikeness = createdBand.AsSource().OfLikeness<DrumAndBassBand>()
.Without(x => x.Bass)
.CreateProxy();
createdLikeness.Drum = createdBand.Drum;
Assert.True(createdLikeness.Equals(template));
var templateLikeness = template.AsSource().OfLikeness<DrumAndBassBand>()
.Without(x => x.Bass)
.CreateProxy();
templateLikeness.Drum = template.Drum;
Assert.True(templateLikeness.Equals(createdBand));
}
In the second test, the Drum and Bass instances are different from the template where you are trying to compare.
You can always run a Likeness (without creating a Proxy) and inspect the output:
Test 'DrumAndBassBand_Equality_Behaves_As_Expected_Version_Two' failed:
Ploeh.SemanticComparison.LikenessException:
The provided value DrumAndBassBand did not match the expected value DrumAndBassBand.
The following members did not match:
- Drum.
That basically means that you have to provide a hint when creating a Likeness for the the comparison of the Drum instance.
The first half of the test becomes:
var createdLikeness = createdBand
.AsSource().OfLikeness<DrumAndBassBand>()
.With(x => x.Drum)
.EqualsWhen((s, d) => s.Drum == createdBand.Drum)
.Without(x => x.Bass)
.CreateProxy();
The source destination's Drums equals other Drums when it is really a createdBand instance Drum.
Similarly, the second half of the test becomes:
var templateLikeness = template
.AsSource().OfLikeness<DrumAndBassBand>()
.With(x => x.Drum)
.EqualsWhen((s, d) => s.Drum == template.Drum)
.Without(x => x.Bass)
.CreateProxy();
The above allow you to have very flexible comparisons (and you can always customize it even further).

Binding Data To DropDownList MVC Razor

I have just started with my project using MVC and Razor. Now I am encountering a problem when it comes to binding data coming from the database to a dropdownlist. Please refer on my codes below:
Specialization Model:
public class SpecializationModel
{
[Display(Name = "SpecializationID")]
public string SpecializationID { get; set; }
[Display(Name = "SpecializationDescription")]
public string SpecializationDescription { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
public int SelectedSpecializationID { get; set; }
}
Controller:
public ActionResult Physicians()
{
SpecializationManager spec = new SpecializationManager();
List<Specialization> SpecializationList = spec.GetAllSpecialization();
var obj = new SpecializationModel();
obj.Items = new[]
{
foreach(var x in SpecializationList)
{
new SelectListItem { Value = x.SpecializationID.ToString(), Text = x.SpecializationDescription };
}
};
return View(obj);
}
I have this manager which contains my LINQ query to extract the data from the database.
I encounter problems on the controller. Wherein the error points on the foreach syntax saying Invalid expression term foreach
Can anyone please point me to the right direction? Thanks a lot!
EDIT:
I have this code now without errors on the foreach part (thanks to the post below which I combined with what I have above). However, I can't seem to make the last line work. It produces an error about implicit cast:
var items = new List<SelectListItem>();
foreach (var x in SpecializationList)
{
items.Add(new SelectListItem { Value = x.SpecializationID.ToString(), Text = x.SpecializationDescription });
}
obj.Items = items.ToList();
Please do help me. Thanks :)
yopu can't put a foreach in a constructor, try:
var items = new List<SelectListItem >();
foreach(var x in SpecializationList)
{
items.add(new SelectListItem { Value = x.SpecializationID.ToString(), Text = x.SpecializationDescription });
}
obj.Items = items;
Edited

Resources