I'm having a list of strings whit some values and I want to make some kind of variable for keeping code that I will be using in template file.
For example lets say I have list with this 3 string values: configService, scaleCoefConfigService, sessionService. Name of the list is chItemName.
And I need to generate this kind of code that I will parse later into template:
[Dependency("configService")]
[Dependency("scaleCoefConfigService")]
[Dependency("sessionService")]
So my question is can make some variable and mechanism for iterating thou list of strings that adds every single item from list to variable?
I've tried this:
foreach (var tp in controllerChecked)
{
var genCode = "[Dependency](" '"' + chItemName + '"'")] \n"
}
controllerChecked is collection of objects and one of the objects value is Name that I'm getting like this:
var chItemName = controllerChecked.Select(c => c.Name).ToList();
This is how the list chItemName is getting those strings.
But of course it is impossible to use + with lists and this kind of stuff will never work. Someone has better idea?
In your example, you are not using the tp variable, which contains will contain each of the values within controllerChecked, one at a time.
You could just iterate through the chItemName list and add the result to a StringBuilder:
StringBuilder codeBuilder = new StringBuilder();
foreach (string tp in chItemName)
{
codeBuilder.AppendLine("[Dependency(\"" + tp + "\")]");
}
string code = codeBuilder.ToString();
If controllerChecked contains more information, you could also directly access it:
StringBuilder codeBuilder = new StringBuilder();
foreach (var item in controllerChecked)
{
string propertyName = item.Name.SubString(1);
codeBuilder.AppendLine("[Dependency(\"" + item.Name + "\")]");
codeBuilder.AppendLine("public " + item.Type + " " + propertyName + " { get; set; }");
codeBuilder.AppendLine();
}
string code = codeBuilder.ToString();
PS. I would definitely change the name of chItemName to chItemNames as it is a list, but that is up to you of course.
This worked perfectly good. I have little bit harder version of this, if you can figure out how to do this:
Lets say that instead of one chItemName list I have 2 more: fName and chItemType, both are string lists.
And I have to generate this kind of code:
[Dependency("alarmsService")]
public IAlarmsService AlarmsService { get; set; }
[Dependency("jsonFactory")]
public IJSONFactoryService JsonFactory { get; set; }
[Dependency("dataBean")]
public IDataBean DataBean { get; set; }
alarmsServise, jsonFactory and dataBean are items of chItemName.
IAlarmsService, IJSONFactoryService and IDataBean are items of chItemType.
AlarmsService, Json Factory and DataBean are items of fName list.
fName is list that I got from chItemType by trimming the first letter from each string in list:
List<string> fName = new List<string>();
foreach(var i in chItemType)
{
var newName = i.Remove(0,1);
fName.Add(newName);
}
So only that list is not a part of controllerChecked list. The othere two are defined like this:
var chItemType = controllerChecked.Select(c => c.Type).ToList();
var chItemName = controllerChecked.Select(c => c.Name).ToList();
Can I edit foreach somehow or maybe I can make parts of code with StringBulider and after that merged them together?
Related
I've got dates from separate countries within a single List<>. I'm trying to get two records that contain the same characters before the second comma, and replace BOTH of those items with a new one.
Example:
From This:
18/04/2014,Good Friday,England and Wales
18/04/2014,Good Friday,Scotland
Into this:
18/04/2014,Good Friday,"England, Wales and Scotland"
Please note there may be multiple scenarios within the list like the above example. I've managed to get everything before the second Comma with:
splitSubstring = line.Remove(line.LastIndexOf(','));
I've tried the below, but it's clearly flawed since it won't delete both the records even if it does find a match:
foreach (var line in orderedLines)
{
if (splitSubstring == line.Remove(line.LastIndexOf(',')))
{
//Replace if previous is match here
}
splitSubstring = line.Remove(line.LastIndexOf(','));
File.AppendAllText(correctFile, line);
}
I would suggest parsing it into a structure you can work with e.g.
public class HolidayInfo
{
public DateTime Date { get; set; }
public string Name { get; set; }
public string[] Countries { get; set; }
};
And then
string[] lines = new string[]
{
"18/04/2014,Good Friday,England and Wales",
"18/04/2014,Good Friday,Scotland"
};
// splits the lines into an array of strings
IEnumerable<string[]> parsed = lines.Select(l => l.Split(','));
// copy the parsed lines into a data structure you can write code against
IEnumerable<HolidayInfo> info = parsed
.Select(l => new HolidayInfo
{
Date = DateTime.Parse(l[0]),
Name = l[1],
Countries = l[2].Split(new[] {",", " and " }, StringSplitOptions.RemoveEmptyEntries)
});
...etc. And once you have it in a helpful data structure you can begin to develop the required logic. The above code is just an example, the approach is what you should focus on.
I ended up using LINQ to pull apart the List and .Add() them into another based on an if statement. LINQ made it nice and simple.
//Using LINQ to seperate the two locations from the list.
var seperateScotland = from s in toBeInsertedList
where s.HolidayLocation == scotlandName
select s;
var seperateEngland = from e in toBeInsertedList
where e.HolidayLocation == engAndWales
select e;
Thanks for pointing me to LINQ
I am using HtmlAgilityPack to find all items, colours and links to products on a website. I want to be able to find an item on the website by typing in the name and colour inside my application.
So far what I have working is:
The application finds items using only the item name and returns the last thing on the website with that name. There are multiple products with the same name but each have a different colour.
The problem comes in when including colour because it's in a different XPath so it's stored in a different collection.
Here is my code:
HtmlNodeCollection collection = doc.DocumentNode.SelectNodes("//*[contains(#class,'inner-article')]//h1//a");
HtmlNodeCollection collection2 = doc.DocumentNode.SelectNodes("//*[contains(#class,'inner-article')]//p//a");
foreach (var node2 in collection2)
{
string coloursv = node2.InnerHtml.ToString();
strColour = coloursv;
//txtLog.Text += Environment.NewLine + (DateTime.Now.ToString("hh:mm:ss")) + str; - This code returns all colours (If code is ran outside of collection then only last colour in string is returned.
}
foreach (var node in collection)
{
string href = node.Attributes["href"].Value;
var itemname = node.InnerHtml.ToString();
if (itemname.Contains(txtKeyword.Text))
{
txtLog.Text = (DateTime.Now.ToString("hh:mm:ss")) + " - Item Found: " + href + " " + itemname + " " + strColour; //Successfully returns item name, colour and link but always gives last availible on website
}
}
This is because you are continually setting the Text property of a textbox within a loop (so each item will continually overwrite the previous):
foreach (var node in collection)
{
// Omitted for brevity
// This will continually overwrite the contents of your Text property
txtLog.Text = ...;
}
If you want to store multiple items, you'll either need to store the results in some type of a collection object (such as a ListBox, etc.) or by simply concatenating your values into the textbox:
foreach (var node in collection)
{
// Omitted for brevity
var stringToAdd = ...;
txtLog.Text += stringToAdd + Environment.NewLine;
}
You can also accomplish this by using the StringBuilder class to be a bit more efficient:
StringBuilder sb = new StringBuilder();
foreach (var node in collection)
{
// Omitted for brevity
var stringToAdd = ...;
// Append this item to the results
sb.AppendLine(stringToAdd);
}
// Store the results
txtLog.Text = sb.ToString();
I have a text file that contains product information on each line, in the form of "productCode,productName,amountInStock,etc.."
I've used File.ReadAllLines to store each line as an element in an array, and now I'm using those strings to assign values to a list of product structs.
Here is the code being used to split those strings from the array into substrings:
foreach (String line in readProducts)
{
productData = line.Split(',');
readProducts[foreachCount] = productData;
foreachCount++;
}
Which gives me this error in Visual Studio:
Cannot implicitly convert type 'string[]' to 'string'
What would be the best way to accomplish this task, assuming that I must use structs rather than classes?
Use this way
List<string[]> readProducts = new List<string[]>();
foreach (String line in readProducts)
{
productData = line.Split(',');
readProducts.Add(productData);
}
Here is a better option for you:
Let product be the class, contains properties such as productCode, productName,amountInStock,etc.. as you mentioned in the question. you can create a list of product and directly assign the input values to the list as like the following:
string path="path here"
List<product> ProductList = new List<product>();
foreach (string line in File.ReadAllLines(path))
{
string[] productDetails = line.Split(',');
ProductList.Add(new product() { productCode = productDetails[0], productName = productDetails[1] });
}
Where the Product class looks like:
public class product
{
public string productCode { get; set; }
public string productName { get; set; }
// rest of properties
}
You can use Select to project to a new collection:
var allItems = readProducts.Select(line => line.Split(',')); // collection of string arrays
or to project to a new type:
var allProducts = readProducts.Select(line => line.Split(',')) // collection of string arrays
.Select(array => new Product {
productCode = array[0],
productName = array[1],
amountInStock = array[2],
// etc.
}); // collection of Products
Using System and jagged arrays, I was able to solve the problem. Here is the code used in the working program.
int i = 0;
String[][] allProducts = new String[readProducts.Length][];
var parsedProduct = readProducts.Select(item => item.Split(','));
foreach (var item in parsedProduct)
{
allProducts[i] = item;
i++;
}
allProducts[][] is a jagged array. Otherwise known as an Array of Arrays.
parsedProduct is similar to the jagged array, each element contains another array with the substrings extracted from the current line of readProduct as their elements.
allProducts's elements are assigned the contents of parsedProducts's elements by the foreach loop.
As far as I can tell, there isn't any way to cut out the middle man and just use Select() on readProducts directly. But I could be wrong.
I'm new to programming and I thought it would be great to start with something a bit simple but useful for me and my girlfriend.
I would like to create a shopping list program that will take my items that I input into the textbox and then sort them based on defined groups. Then output that information in an easy to read list already categorized for easy shopping.
My question is this; How do I sort information that I put into a rich textbox? I have two rich textboxes and I would like to input information into one and then output that information to the other but have it sorted to my preferences.
Thank you in advance. :-)
Since you want to group them, I would suggest creating a small GroceryItem like this:
class GroceryItem
{
GroceryItem(string category, string name) {
Category = category;
ItemName = name;
}
public string Category {get;set;}
public string ItemName {get;set;}
}
Then you can easily parse from your first text box the items. Let's assume they look like this:
Vegies, Tomato
Meat, Lamb
Vegies, Potato
Meat, Chicken
Just read them all, split on , to get 2 parts for each, and create a new GroceryItem:
List<CategoryItem> shoppingList = new List<CategoryItem>();
foreach (var line in your_lines_collection)
{
var parts = some_line.Split(',');
shoppingList.Add(new GroceryITem(parts[0],parts[1]));
}
And last, but not least, once you have a list of those (shoppingList), you can use linq to sort to your heart content. Here's an example:
List<GroceryItem> shoppingList = new List<GroceryItem>();
List<string> groceries = new List<string>(){"veg, pot", "veg, tom", "meat, chicken", "meat, veal"};
foreach (var line in groceries)
{
var parts = line.Split(',');
shoppingList.Add(new GroceryItem(parts[0],parts[1]));
}
var sorted_list_by_ItemName =
from item in shoppingList
orderby item.ItemName
group item by item.Category into groups
select groups
;
foreach (var gr in sorted_list_by_ItemName)
{
Console.Out.WriteLine("[{0}] :", gr.Key);
foreach (var it in gr)
Console.Out.WriteLine(" {0}", it);
}
This will output:
[meat] :
meat , chicken
meat , veal
[veg] :
veg , pot
veg , tom
You then can just print this on your other textbox, or work with it as you wish :)
As per comments, here's the whole code for a console, just paste it into your visual studio, and it should work:
using System;
using System.Collections.Generic;
using System.Linq;
internal class Program
{
public static void Main(string[] args)
{
List<GroceryItem> shoppingList = new List<GroceryItem>();
List<string> groceries = new List<string>() { "veg, pot", "veg, tom", "meat, chicken", "meat, veal" };
foreach (var line in groceries)
{
var parts = line.Split(',');
shoppingList.Add(new GroceryItem(parts[0], parts[1]));
}
var sorted_list_by_ItemName =
from item in shoppingList
orderby item.ItemName
group item by item.Category into groups
select groups;
foreach (var gr in sorted_list_by_ItemName)
{
Console.Out.WriteLine("[{0}] :", gr.Key);
foreach (var it in gr)
Console.Out.WriteLine(" {0}", it);
}
Console.ReadKey();
}
public class GroceryItem
{
public GroceryItem(string category, string name)
{
Category = category;
ItemName = name;
}
public string Category { get; set; }
public string ItemName { get; set; }
public override string ToString()
{
return Category + " , " + ItemName;
}
}
}
To avoid an ongoing ping pong, if you have another question, just open a new one (if it's relevant). Otherwise, you can upvote,downvote, and mark as answered if this answered your question. :)
Well, if your first RichTextBox has each item separated by something known (e.g. NewLine), then it should be as straight forward as this:
var list = richTextBox1.Text
.Split(new[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries)
.Sort();
richTextBox2.Text = string.Join(Environment.NewLine, list.ToArray());
This will leverage the default sorting algorithm for the type. In this case string. So it will sort them alphabetically.
I have list that have values like"
[0] = "{ id = ES10209005, views = 501 }"
[1] = "{ id = HYT0209005, views = 5678}"
[3] = "{ id = POI0209005, views = 4568}"
I would like to pass the values(id,views) to a method using a for each loop.
method(id,views)
Something like:
foreach (string v in updatereponse)
{
method()
}
How do I isolate each value(id,views) from each row in the list then pass it to the method?
The list contains just a bunch of strings, anything based on this to fix the problem would be just a workaround (e.g. string parsing). You should really switch to a strongly typed model, e.g. define a class ViewCount:
public class ViewCount
{
public string Id {get;set;}
public int Views {get;set;}
}
You can then use a List<ViewCount> populate the list:
List<ViewCount> viewcounts = new List<ViewCount>();
viewCounts.Add(new ViewCount() { Id = "ES10209005", Views = 501 });
Since each ViewCount instance has Id and Views properties you can now do the proper thing:
foreach (var item in updatereponse)
{
method(item.Id, item.Views);
}
If you are saving this data in a file, an alternative would be to use XML instead of custom strings, then you could use Linq to XML to populate a List<ViewCount>, e.g. using a simple XML like this:
<ViewCounts>
<ViewCount id="ES10209005" views="501" />
</ViewCounts>
You can then load your list:
XElement viewXml = XElement.Load("test.xml");
List<ViewCount> viewCounts = viewXml.Descendants("ViewCount")
.Select(x => new ViewCount()
{
Id = (string)x.Attribute("id"),
Views = (int)x.Attribute("views")
}).ToList();
foreach (string v in updateresponse)
{
var values = v.Split(",");
var id = values[0].Replace("{ id = ", "").Trim();
var view = values[1].Replace("views = ", "").("}","").Trim();
method(id, value);
}
Here's another way...you may want to add error checking:
String Data = "{ id = ES10209005, views = 501 }";
String[] Segments = Data.Split(new char[] { ' ', ',' });
string ID = Segments[3];
int views = int.Parse(Segments[7]);
Assuming the structure of your String is like you showed us always, this can work for you.
// First split id and views part.
String[] firstSplit = v.Split(',');
// Get the respected value for each part.
String id = firstSplit[0].Split('=')[1].Trim();
String views = firstSplit[1].Split('=')[1].Trim().Replace("}","");
You can use String methods to retrieve the items (use Split and SubString for example) or you can use a regular expression.
E.g.
var list = UpdateResponse[0].Split("=,} ") ;
will result in a list split by all these characters (including space).
Then check the correct indices to use (use a debugger for that). Then you get something like:
var id = list[5];
var views = list[8];
(note: check the indices 5 or 8, they are just a guess).