Simple way to split and joiin a string with Object Initializer? - c#

Is there a way to shorten this code below. (expecting 20+ values)
The values will always remain in the same order.
string[] values = line.Split(',');
LogEntry entry = new LogEntry()
{
Id = values[0],
Service = values[1],
Name = values[2],
Process = values[3],
type = values[4]
[...]
};

I personally do not know of a simplified way of doing this -- somewhere this code would need to exist. However, you could use a mapper solution like AutoMapper to set up a mapping. At least this your handlers or actions aren't bloated with assignment logic.
Hope this helps a bit.
Looking forward to reading other answers.

You can add to LogEntry constructor with one param string line and move logic into constructor.
Then code will be look like
LogEntry entry = new LogEntry(line);
And in constructor something like this:
public void LogEntry(string line)
{
string[] values = line.Split(',');
Id = values[0],
Service = values[1],
Name = values[2],
Process = values[3],
type = values[4]
[...]
}
This code must be somewhere.
Is it better solution depends on the situation. If you often used the object initializer that will greatly simplify the code. If you do not it's probably not have much of a difference.

From your question, you are trying to avoid those twenty lines of setting the values. How about using a reflection based solution like the one below ?
string[] values = line.Split(',');
var orderedLogEntryPropertyNames =
new string[]{ "Id", "Name", "Process" };
//list all the LogEntry property names in the order that map to the values
var logEntry = new LogEntry();
var logEntryProperties = typeof(LogEntry).GetProperties();
for (int i = 0; i < values.Length; i++)
{
var propertyToSet =
logEntryProperties.First(p => p.Name.Equals(orderedLogEntryPropertyNames[i]));
propertyToSet.SetValue(logEntry, values[i]);
}

Related

Using linq with string split

workareaRefs is a string of random values splitted by comma i.e. 4,7,1,7 etc.
I am setting properties to TrackDataFilter and would like to set the Workareas
which is of type IList with the values in workareaRefs var.
So Workareas should contain the values in workareaRefs stored in the variable named r.
Can anyone help me achieve this?
var workareasRefs = workareaRefs.Split(',');
var r = new TrackDataFilter
{
DatePreset = preset,
Workareas = new List<TrackFilterGenericRef>
{
new TrackFilterGenericRef
{
Ref = 2, Type = Enums.ContentTypes.Workarea
}
},
};
Well, I am not sure If I understand your question correctly, so by guessing a bit, I would assume you want to do the following
WorkAreas = new List(workareasRefs);

object' does not contain a definition for MainTypeCode for dynamic data

This below query return some mock data for unit testing.
var colorsList = (IEnumerable<dynamic>)colorsRepository.GetColorsList().Result;
It given the result as dynamic object
I want to get MainTypeCode value only. But it is showing object' does not contain a definition for MainTypeCode
colorsList.Select(cl => (dynamic)cl.MainTypeCode);
Edit:
And let me know how to arrange dummy/mock dynamic data to execute the query?
and colorsRepository.GetColorsList().Result; is returning below way. Shall I change the mock data to run the query?
public static IEnumerable<dynamic> GetColorsList()
{
List<dynamic> colours = new List<dynamic>();
for (int i = 0; i < 1; i++)
{
colours.Add((dynamic)new
{
MainTypeCode = 1,
DoorCode = "001"
});
}
return colours.AsEnumerable();
}
I'm guessing, the issue might be related with the dynamic. Could you try something like the following?
var colorLists = new [] { new {DoorCode = "001", MainTypeCode = 1}, new {DoorCode = "002", MainTypeCode = 2}};
var mainTypeCodes = colorLists.Select(cl => cl.GetType().GetProperty("MainTypeCode").GetValue(cl, null));
Get value of c# dynamic property via string
Sadly I have much time to elaborate a better answer, but you will have to use reflection in order to get the dynamic properties.
If you know the dynamic properties before hand you can try to do a class and create a Map method with reflection to get the object.

C# variable assignment

Can someone show me a simple way to assign variables.
I have many variables and not really know how to do, whether it be possible to use a loop?`
public void SwappingPlaces1()
{
Section_1[0] = Receiver_1[0];
Section_1[1] = Receiver_2[0];
Section_1[2] = Receiver_3[0];
Section_1[3] = Receiver_4[0];
Section_1[4] = Receiver_5[0];
Section_1[5] = Receiver_6[0];
Section_1[6] = Receiver_7[0];
Section_1[7] = Receiver_8[0];
Section_1[8] = Receiver_9[0];
Section_1[9] = Receiver_10[0];
Section_1[10] = Receiver_11[0];
Section_1[11] = Receiver_12[0];
Section_1[12] = Receiver_13[0];
Section_1[13] = Receiver_14[0];
Section_1[14] = Receiver_15[0];
Section_1[15] = Receiver_16[0];
Section_1[16] = Receiver_17[0];
Section_1[17] = Receiver_18[0];
Section_1[18] = Receiver_19[0];
Section_1[19] = Receiver_20[0];
Section_1[n] = Receiver_n[0];
...
}
You need to use reflection to get the names of the properties/fields by their name. Assuming Reciever_n is a property:
var properties = this.GetType().GetProperties();
for(int i = 0; i < n; i++)
{
var p = properties.Single(x => x.Name == "Receiver_" + i);
var value = p.GetValue(this, new object[] { 0 });
}
First you get all the properties defined on the type. Now you loop your list and get that single property with the name Receiver_ plus the current index.
Finally you invoke that property on the instance and provide the index of the indexed property (which is equal to zero here).
EDIT: However having so many properties with equal name and type seems a design-flaw, you should consider your actual design.
Thus a better appraoch might be to have just one single two-dimensional array Receiver.
You could add reference variables to an array and iterate over them. This is mostly usefull, clearing gui controls, like textboxes/labels etc.
var variables = new[] { Receiver_1, Receiver_2, Receiver_3, Receiver_4,
Receiver_5, Receiver_6 };
for(int i=0; i<Section_1.Length;i++)
Section_1[i] = variables[i][0];
But an index out of bounds is easely created
You could also use reflection.

Querying a list of strings with a query string?

I have a dictionary:
<string,List<string>>
The key is the product code say "product1" then the list is a list of properties:
"Brand","10.40","64","red","S"
Then I 'can' have a list of rules/filters e.g.
var tmpFilter = new customfilters();
tmpFilter.Field = "2";
tmpFilter.Expression = ">";
tmpFilter.Filter = "10";
So for the above example this would pass because at index 2 (tmpFilter.Field) it is more than 10; then I have another object which defines which fields within the list I want to write to file. For that dictionary item I just want to write the product brand and price where the filters match.
At the moment without the filter I have:
var tmp = new custom();
tmp.Columns = "0,1";
tmp.Delimiter = ",";
tmp.Extention = ".csv";
tmp.CustomFilters = new List<customfilters>() {new customfilters(){ Field = "2", Expression = ">", Filter = "10"} };
public static void Custom(custom custom)
{
foreach (var x in Settings.Prods)
{
//Get Current Product Code
var curprod = Settings.ProductInformation[x];// the dictionary value
foreach (var column in custom.Columns)
{
var curVal = curprod[Convert.ToInt32(column)];
tsw.Write(curVal + custom.Delimiter);
}
Settings.Lines++;
tsw.WriteLine();
}
tsw.Close();
}
I only want to write the curprod if all the filters pass for that list of strings.
How I can do this?
There's a really nice Nuget package based on an example published by Microsoft, that they have decided to make really hard to find for some reason, that allows dynamic linq queries:
https://www.nuget.org/packages/System.Linq.Dynamic/1.0.2
Source:
https://github.com/kahanu/System.Linq.Dynamic
Using that you can do stuff like this very easily (note: I used strings here because the OP states they have a List<string>):
List<string> stuff = new List<string> { "10.40", "64", "5", "56", "99", "2" };
var selected = stuff.Select(s => new { d = double.Parse(s) }).Where("d > 10");
Console.WriteLine(string.Join(", ", selected.Select(s => s.d.ToString()).ToArray()));
Outputs:
10.4, 64, 56, 99
That may give you a place to start. One thing you are going to have to tackle is identifying which of your fields are numeric and should be converted to a numeric type before trying to apply your filter. Otherwise you are going to comparing as strings.

Map two string arrays without a switch

I have two arrays that need to be mapped. In code
var result = "[placeholder2] Hello my name is [placeholder1]";
var placeholder = { "[placeholder1]", "[placeholder2]", "[placeholder3]", "[placeholder4]" };
var placeholderValue = { "placeholderValue3", "placeholderValue2", "placeholderValue3" };
Array.ForEach(placeholder , i => result = result.Replace(i, placeholderValue));
given i, placeholderValue needs to be set in an intelligent way. I can implement a switch statement. The cyclomatic complexity would be unacceptable with 30 elements or so. What is a good pattern, extension method or otherwise means to achieve my goal?
I skipped null checks for simplicity
string result = "[placeholder2] Hello my name is [placeholder1]";
var placeHolders = new Dictionary<string, string>() {
{ "placeholder1", "placeholderValue1" },
{ "placeholder2", "placeholderValue2" }
};
var newResult = Regex.Replace(result,#"\[(.+?)\]",m=>placeHolders[m.Groups[1].Value]);
The smallest code change would be to just use a for loop, rather than a ForEach or, in your case, a ForEach taking a lambda. With a for loop you'll have the index of the appropriate value in the placehoderValue array.
The next improvement would be to make a single array of an object holding both a placeholder and it's value, rather than two 'parallel' arrays that you need to keep in sync.
Even better than that, and also even simpler to implement, is to just have a Dictionary with the key being a placeholder and the value being the placeholder value. This essentially does the above suggestion for you through the use of the KeyValuePair class (so you don't need to make your own).
At that point the pseudocode becomes:
foreach(key in placeholderDictionary) replace key with placeholderDictionary[key]
I think you want to use Zip to combine the placeholders with their values.
var result = "[placeholder2] Hello my name is [placeholder1]";
var placeholder = new[] { "[placeholder1]", "[placeholder2]", "[placeholder3]", "[placeholder4]" };
var placeholderValue = new[] { "placeholderValue1", "placeholderValue2", "placeholderValue3", "placeholderValue4" };
var placeHolderPairs = placeholder.Zip(placeholderValue, Tuple.Create);
foreach (var pair in placeHolderPairs)
{
result = result.Replace(pair.Item1, pair.Item2);
}

Categories