loop through database item, sum values and parse unwanted text - c#

I am wondering about for each loop. What I have is several columns for each item and I want to loop trough it and take out values from each column that has the name "inch".
Now to the part where the value is not just numbers but also letters, like "1 inch".
So I have 3 items that has "1 inch","5 inch" and "10 inch".
So I want to take the "inch" (parse I guess) out and add these three together so the sum is 16.
This if for windows phone local database c#
I have a ViewModel and a Model. The columns in the Model looks like this
private string _itemSpring;
[Column]
public string ItemSpring
{
get { return _itemSpring; }
set
{
if (_itemSpring != value)
{
NotifyPropertyChanging("ItemSpring");
_itemSpring = value;
NotifyPropertyChanged("ItemSpring");
}
}
}
Then i view it through my viewmodel with connection string to db,
// LINQ to SQL data context for the local database.
public ToDoDataContext toDoDB;
// Class constructor, create the data context object.
public ToDoViewModel(string toDoDBConnectionString)
{
toDoDB = new ToDoDataContext(toDoDBConnectionString);
}

If your 3 items are like this,
string[] items = { "1 inch", "5 inch", "10 inch" };
int totalCount = 0;
foreach(var item in items)
{
string[] substrings = item.split(' ');
totalCount += int.Parse(substrings[0]);
}
string finalString = totalCount + " inch";
UPDATE:
I dont understand whether you are asking on how to retrieve the data from database or how to process the data that is fetched from DB.
Assuming the second case, check the following answer
Fetch the data from database and convert it into a List or an ObservableCollection
and then you can use the following query on that to get what you want.
foreach(var item in ItemsList)
totalCount += double.Parse(item.ItemSize.Split(' ')[0]);
or otherwise
foreach(var item in ItemsList)
totalCount += double.Parse(item.ItemSize.Replace(" inch", ""));

Related

Update Multiple Table Rows in Service from a list viewmodel?

I have a view model whose values ​​are sent as a list from the view for edit four input boxs ...
public class UpdatePollViewModel
{
public List<string> Answer { get; set; }
}
In my service, I got the same values ​​from the database via Id:
public bool UpdatePoll(Guid id, UpdatePollViewModel viewModel)
{
var polloption = _context.PollOptions.Where(p => p.PollId == Id).ToList();
}
I used this but it does not make sense because it repeats a lot!!!
foreach (string item in viewModel.Answer)
{
foreach (var item2 in polloption)
{
item2.Answer = item;
_context.SaveChanges();
}
}
What is the best way to handle this?
I'm going to assume that the magic number is 4.
There are 4 input boxes that are used to populate the view model list with 4 answers in the same order as the existing 4 answers that are retrieved from the database and you want to map the 4 inputs to the 4 records from the database.
var polloption = _context.PollOptions.Where(p => p.PollId == Id).ToList();
for (int i = 1; i <= 4; i++)
{
polloption[i-1].Answer = viewModel.Answer[i-1];
}
_context.SaveChanges();

Creating and Displaying multiple arrays simultaniously C#

I'm new to C# and programming as a whole and I've been unable to come up with a solution to what I want to do. I want to be able to create a way to display several arrays containing elements from three external text files with values on each line (e.g. #"Files\Column1.txt", #"Files\Column2.txt" #"Files\Column3.txt"). They then need to be displayed like this in the command line:
https://www.dropbox.com/s/0telh1ils201wpy/Untitled.png?dl=0
I also need to be able to sort each column individually (e.g. column 3 from lowest to highest).
I've probably explained this horribly but I'm not sure how else to put it! Any possible solutions will be greatly appreciated!
One way to do it would be to store the corresponding items from each file in a Tuple, and then store those in a List. This way the items will all stay together, but you can sort your list on any of the Tuple fields. If you were doing anything more detailed with these items, I would suggest creating a simple class to store them, so the code would be more maintainable.
Something like:
public class Item
{
public DayOfWeek Day { get; set; }
public DateTime Date { get; set; }
public string Value { get; set; }
}
The example below could easily be converted to use such a class, but for now it uses a Tuple<string, string, string>. As an intermediate step, you could easily convert the items as you create the Tuple to get more strongly-typed versions, for example, you could have Tuple<DayOfWeek, DateTime, string>.
Here's the sample code for reading your file items into a list, and how to sort on each item type:
public static void Main()
{
// For testing sake, I created some dummy files
var file1 = #"D:\Public\Temp\File1.txt";
var file2 = #"D:\Public\Temp\File2.txt";
var file3 = #"D:\Public\Temp\File3.txt";
// Validation that files exist and have same number
// of items is intentionally left out for the example
// Read the contents of each file into a separate variable
var days = File.ReadAllLines(file1);
var dates = File.ReadAllLines(file2);
var values = File.ReadAllLines(file3);
var itemCount = days.Length;
// The list of items read from each file
var fileItems = new List<Tuple<string, string, string>>();
// Add a new item for each line in each file
for (int i = 0; i < itemCount; i++)
{
fileItems.Add(new Tuple<string, string, string>(
days[i], dates[i], values[i]));
}
// Display the items in console window
fileItems.ForEach(item =>
Console.WriteLine("{0} {1} = {2}",
item.Item1, item.Item2, item.Item3));
// Example for how to order the items:
// By days
fileItems = fileItems.OrderBy(item => item.Item1).ToList();
// By dates
fileItems = fileItems.OrderBy(item => item.Item2).ToList();
// By values
fileItems = fileItems.OrderBy(item => item.Item3).ToList();
// Order by descending
fileItems = fileItems.OrderByDescending(item => item.Item1).ToList();
// Show the values based on the last ordering
fileItems.ForEach(item =>
Console.WriteLine("{0} {1} = {2}",
item.Item1, item.Item2, item.Item3));
}

Adding to columns based on length

I have a ListView with two columns, Boxes and Files. I'm adding items to a list of strings, and then populating the ListView with that list of strings. I want to make it so all items that are 8 characters long go into the Boxes column and all items that are 9 characters go into the Files column. So far, I've tried to iterate through using a for loop and utilize an if else statement to add the items, but I seem to be doing something wrong. Here's my current code:
public void PopulateItemsList()
{
BoxAndFileList.Items.Clear();
ScanIdBox.Text = string.Empty;
for (int i = 0; i < BoxNumberRepository._boxAndFileList.Count; i++)
{
var item = BoxNumberRepository._boxAndFileList.Item[i];
if (item.Length == 8)
{
BoxAndFileList.Items.Insert(0, item);
}
else
{
BoxAndFileList.Items.Insert(1, item);
}
}
}
I'm iterating through my list (_boxAndFileList) and trying to utilize Insert() to insert items into the specific index of the columns (Boxes is 0, Files is 1). I can clearly see that Item is a legitimate property of a string list, yet VS keeps saying that list contains no definition of it. How can I go about doing this? And also, I haven't received outside feedback on this way of doing things yet, so if there's a better way, please let me know.
Edit: BoxNumberRepository is a class that news up a list called _boxAndFileList. Code below:
public class BoxNumberRepository : Scan_Form
{
public static List<string> _boxAndFileList = new List<string>();
public void AddItem(string item)
{
_boxAndFileList.Add(item);
}
public void Delete(string item)
{
_boxAndFileList.Remove(item);
}
public IEnumerable<string> GetAllItems()
{
return _boxAndFileList;
}
}
Thanks to Alessandro D'Andria for that suggestion. That was correct. However, all the items are still just adding to the first column, even if they're 9 characters. How can I get 9 character items to add to the second column?
The problem that you are having is that you have to add both the box and file to the list item at the same time.
EDIT: Changed cartesian product to a left outer join.
EDIT: Added comments and fixed a syntax bug
private List<string> _boxAndFileList = new List<string> { "12345678", "123456789", "1234", "123456778" };
public void PopulateItemsList()
{
//clear the list
BoxAndFileList.Items.Clear();
//add the labels to the top of the listbox
BoxAndFileList.Columns.Add("Boxes");
BoxAndFileList.Columns.Add("Files");
//set the view of the list to a details view (important if you try to display images)
BoxAndFileList.View = View.Details;
//clear scan id box
ScanIdBox.Text = string.Empty;
//get all the items whos length are 8 as well as a unique id (index)
var boxes = _boxAndFileList.Where(b => b.Length == 8).Select((b, index) => new { index, b }).ToList();
//get all the items whos length are NOT 8 as well as a unique id (index)
var files = _boxAndFileList.Where(f => f.Length != 8).Select((f, index) => new { index, f }).ToList();
//join them together on their unique ids so that you get info on both sides.
var interim = (from f in files
join b in boxes on f.index equals b.index into bf
from x in bf.DefaultIfEmpty()
select new { box = (x == null ? String.Empty : x.b), file = f.f });
//the real trick here is that you have to add
//to the listviewitem of type string[] in order to populate the second, third, or more column.
//I'm just doing this in linq, but var x = new ListViewItem(new[]{"myBox", "myFile"}) would work the same
var fileboxes = interim.Select(x => new ListViewItem(new []{ x.box, x.file})).ToArray();
//add the array to the listbox
BoxAndFileList.Items.AddRange(fileboxes);
//refresh the listbox
BoxAndFileList.Refresh();
}
Your _boxAndFileList is a List<string> so you should be declare item as string type instead var type:
string item = BoxNumberRepository._boxAndFileList.Item[i];
All your code should be like this:
public void PopulateItemsList()
{
BoxAndFileList.Items.Clear();
ScanIdBox.Text = string.Empty;
for (int i = 0; i < BoxNumberRepository._boxAndFileList.Count; i++)
{
string item = BoxNumberRepository._boxAndFileList.Item[i];
if (item.Length == 8)
{
BoxAndFileList.Items.Insert(0, item);
}
else
{
BoxAndFileList.Items.Insert(1, item);
}
}
}

Dictionary<int, List<string>>

I have something like this:
Dictionary<int, List<string>> fileList = new Dictionary<int, List<string>>();
and then, I fill it with some variables, for example:
fileList.Add(
counter,
new List<string> {
OFD.SafeFileName,
OFD.FileName,
VERSION, NAME , DATE ,
BOX , SERIAL_NUM, SERIES,
POINT , NOTE , VARIANT
}
);
Where counter is a variable that increment +1 each time something happens, List<string>{XXX} where XXX are string variables that holds some text.
My question is, how do I access these strings from the list, if counter == 1?
You can access the data in the dictionary and lists just like normal. Remember, access a value in the dictionary first, which will return a list. Then, access the items in the list.
For example, you can index into the dictionary, which returns a list, and then index into the list:
------ Returns a list from the dictionary
| --- Returns an item from the list
| |
v v
fileList[0][0] // First item in the first list
fileList[1][0] // First item in the second list
fileList[1][1] // Second item in the second list
// etc.
FishBasketGordo explains how you can access entries in your data structure. I will only add some thoughts here:
Dictionaries (based on hash tables) allow fast access to arbitrary keys. But your keys are given by a counter variable (counter = 0, 1, 2, 3, 4 ...). The fastest way to access such keys is to simply use the index of an array or of a list. Therefore I would just use a List<> instead of a Dictionary<,>.
Furthermore, your list seems not to list anonymous values but rather values having very specific and distinct meanings. I.e. a date is not the same as a name. In this case I would create a class that stores these values and that allows an individual access to individual values.
public class FileInformation
{
public string SafeFileName { get; set; }
public string FileName { get; set; }
public decimal Version { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
...
}
Now you can create a list like this:
var fileList = new List<FileInformation>();
fileList.Add(
new FileInformation {
SafeFileName = "MyDocument.txt",
FileName = "MyDocument.txt",
Version = 1.2,
...
}
}
And you can access the information like this
decimal version = fileList[5].Version;
If the keys don't start at zero, just subtract the starting value:
int firstKey = 100;
int requestedKey = 117;
decimal version = fileList[requestedKey - firstKey].Version;
Dictionary uses Indexer to access its vallues via key.
List<string> items = fileList[counter];
var str0 = items[0];
var str1 = items[1];
Then you can do anything with the list.
Dictionary<int, List<string>> fileList = new Dictionary<int, List<string>>();
fileList.Add(101, new List<string> { "fijo", "Frigy" });
fileList.Add(102, new List<string> { "lijo", "liji" });
fileList.Add(103, new List<string> { "vimal", "vilma" });
for (int Key = 101; Key < 104; Key++)
{
for (int ListIndex = 0; ListIndex < fileList[Key].Count; ListIndex++)
{
Console.WriteLine(fileList[Key][ListIndex] as string);
}
}
You can access the List through MyDic[Key][0]. While editing the list, there won't be any run time errors, however it will result in unnecessary values stored in Dictionary. So better:
assign the MyDict[Key] to new list
edit the new list and then
reassign the new list to MyDict[Key] rather than editing a
particular variable in the Dictionary with List as Values.
Code example:
List<string> lstr = new List<string(MyDict[Key]);
lstr[0] = "new Values";
lstr[1] = "new Value 2";
MyDict[Key] = lstr;

Using Linq to aggregate from array to single var

I have an accordion that binds data for each item from an array.
I want that for every time that I bound the data I will loop through all of the array and aggregate all of the items with the same id and create a long string with a name from a cell. In the code the name oneJob.order_id does not exist and I don't know why.
protected string GetAllProffesions(int orderID)
{
IEnumerable<string> allProf;
orderID = 544;
Job[] curItems = null;
curItems = JobManager.GetJobs(RangeID, GetParam());
allProf = from oneJob in curItems
where oneJob.order_id == orderID
select oneJob.profession_name;
return Convert.ToString(allProf);
}
This is because your job class doesn't have a property called order_id. Check your spelling.
Also, you probably don't want to do Convert.ToString(allProf), as I expect this will give you the type name instead of all the professions concatenated. Try this instead:
string.Join(", ", allProf.ToArray());

Categories

Resources