get a total value from loop items [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Check the code bellow. I am looping to get all value of a returned XML response. But i want to get a total value of all nofwatch variable. How can i add them to get a total value? any idea?
foreach (var sri in searchResultItems)
{
// Get all xml elements
var childElements = sri.Elements();
var nofwatch = childElements.FirstOrDefault(x => x.Name.LocalName == "listingInfo")
.Elements().FirstOrDefault(x => x.Name.LocalName == "watchCount");
//add items from xml data to EbayDataViewModel object
items.Add(new EbayDataViewModel
{
TotalWatchers = nofwatch.Value //how can do + result of all nofwatch value?
});
ViewBag.TotalWatchers = TotalWatchers;
}

var totalValue = 0; //delcare the variable outside the foreach loop
foreach (var sri in searchResultItems)
{
// Get all xml elements
var childElements = sri.Elements();
var nofwatch = childElements.FirstOrDefault(x => x.Name.LocalName == "listingInfo")
.Elements().FirstOrDefault(x => x.Name.LocalName == "watchCount");
//now use += operator to add the result to the totalValue variable
//totalValue += nofwatch.Value;
//nofwatch.Value should be of type string and you would need to parse it as an integer first if that truely is the case
var intValue = 0;
if (int.TryParse(nofwatch.Value, out intValue) == false)
continue;
totalValue += intValue;
}
//outside of the foreach loop use totalValue to set the desired member
ViewBag.TotalWatchers = totalValue;

Related

Check if value already exists in specific indices of List<double[]> [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In the example code below, I need help crafting a line of code in someFunc() that would return a vector of booleans equal to False, True, False, since the value of 100.0 is already contained in the second position of the first item of the list. For the real-world problem I'm working on, I will need to call someFunc repeatedly and the number of vectors (of doubles) added to perv_vals may reach into the thousands.
// set up a list of vectors of type double
public static List<double[]> prev_vals = new List<double[]>();
static void Main(string[] args)
{
double[] arb_vals = new double[3];
bool[] already_exists = new bool[3];
// first example vector to be added to list
arb_vals[0] = 10.0;
arb_vals[1] = 100.0;
arb_vals[2] = 1000.0;
prev_vals.Add(arb_vals.ToArray());
// second example vector to be added to list
arb_vals = new double[3];
arb_vals[0] = 11.0;
arb_vals[1] = 101.0;
arb_vals[2] = 1001.0;
prev_vals.Add(arb_vals.ToArray());
// third example vector to be added to list...could be thousands more
arb_vals = new double[3];
arb_vals[0] = 12.0;
arb_vals[1] = 100.0; # This value already exists at this position!
arb_vals[2] = 1002.0;
// Check whether latest entries of arb_vals
// already exist in their respective indices?
already_exists = someFunc(prev_vals, arb_vals);
// add latest iteration
prev_vals.Add(arb_vals.ToArray());
}
public static bool[] someFunc(List<double[]> prev_vals, double[] arb_vals)
{
bool[] alreadyExists = new bool[arb_vals.Length];
// Need a line of code that would check if values contained in arb_vals
// already exist in prev_vals IN THEIR RESPECTIVE INDICES
return alreadyExists;
}
You can try querying with a help of Linq, e.g.
using System.Linq;
...
bool exists = prev_vals
.Any(array => array.Zip(arb_vals, (a, b) => a == b).Any());
If you just want to know if any combination exists anywhere in the previous array you could write the function like this (notice it returns a single bool):
public static bool someFunc(List<double[]> prev_vals, double[] arb_vals)
{
var count = prev_vals.Where(x => x[0] == arb_vals[0] ||
x[1] == arb_vals[1] ||
x[2] == arb_vals[2]).Count();
return Convert.ToBoolean(count);
}
But in your code sample above, your function returns an array of bools to let you know which value in the array previously exists.
For that you could write the function like this.
I took the lberty of taking it one step further and changing the return type of your function to return a Tuple. Now the function also tells you which index within the array contains the same value.
public Tuple<int, bool, bool, bool> someFunc(List<double[]> prev_vals, double[] arb_vals)
{
// First use select to generate an index for each element of the array
var searchResult = prev_vals.Select((v, i) => new { Index = i, Value = v })
// Then use where to compare values
.Where(x => x.Value[0] == arb_vals[0] ||
x.Value[1] == arb_vals[1] ||
x.Value[2] == arb_vals[2])
// if matches, select a new structure with the index num, and boolean values
.Select(p =>
new
{
Index = p.Index,
val1 = p.Value[0] == arb_vals[0],
val2 = p.Value[1] == arb_vals[1],
val3 = p.Value[2] == arb_vals[2]
})
.FirstOrDefault();
if (searchResult != null)
return Tuple.Create(searchResult.Index, searchResult.val1, searchResult.val2, searchResult.val3);
return null;
}
Update
If the arb_vals array is of variable length that is only known at run time then you need to loop around it to compare. This is going back to basics but this code somply loops through the prev_vals array searching for a match. If it finds one, it exits the function early.
public Tuple<int, int, double> someFunc(List<double[]> prev_vals, double[] arb_vals)
{
for (int nLoopIdx = 0; nLoopIdx < prev_vals.Count; nLoopIdx++)
{
var item = prev_vals[nLoopIdx];
for (int nBoolIdx = 0; nBoolIdx < arb_vals.Length; nBoolIdx++)
{
if (item[nBoolIdx] == arb_vals[nBoolIdx])
{
// This return the loop index,
// the bool index thats the same
// and the the bool value!
return Tuple.Create(nLoopIdx, nBoolIdx, item[nBoolIdx]);
}
}
}
return null;
}
I have also changed the return Tuple to: 2 ints and a double.
The 1st int tells you the index of the clash in the prev_vals array.
The 2nd int is the bool index that has the same value
the double is the value that is the same
Without using Linq you can just cycle the array and the List
bool[] alreadyExists = new bool[arb_vals.Length];
for (int i=0; i < arb_vals.Length; i++) {
foreach (double[] pv in prev_vals){
if (pv[i] == arb_vals[i]){
alreadyExists[i] = true;
continue;
}
}
}
As the array elements are initialized to False, you can just check first time an element is equal and continue to the next index.

How to parse this following string? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have to parse this string
"Cust =Customer CustCR =Customer Credit Prod=Product SalesRep=Sales Rep TaxCat=Tax Category TaxId=Tax ID VolBill=Volume Billing"
as Code, Description like Code=Cust and Description=Customer
split on basis of space is not working for this because there is also a space in description too .
Instead of splitting on space you can split on the equals sign. Then the code will be the value after the last space of the previous item and the description will be everything up to the last space making sure to trim the spaces that might show up before the equals. And you can replace the Dictionary with whatever data type you want to load the values into. Also you have to handle the first and last values as special cases. Note this will only work if the codes do not contain spaces.
string str = "Cust =Customer CustCR =Customer Credit Prod=Product SalesRep=Sales Rep TaxCat=Tax Category TaxId=Tax ID VolBill=Volume Billing";
var separated = str.Split('=');
string code = separated[0].Trim();
var codeAndDescription = new Dictionary<string, string>();
for (int i = 1; i < separated.Length - 1; i++)
{
int lastSpace = separated[i].Trim().LastIndexOf(' ');
var description = separated[i].Substring(0, lastSpace).Trim();
codeAndDescription.Add(code, description);
code = separated[i].Substring(lastSpace + 1).Trim();
}
codeAndDescription.Add(code, separated[separated.Length - 1]);
foreach (var kvp in codeAndDescription)
Console.WriteLine(kvp);
Outputs
[Cust, Customer]
[CustCR, Customer Credit]
[Prod, Product]
[SalesRep, Sales Rep]
[TaxCat, Tax Category]
[TaxId, Tax ID]
[VolBill, Volume Billing]
A little modification for another case if description is empty, also used custom Item class to store output in a list
class Item {
public string Code { get; set; }
public string Description { get; set; }
}
class Program
{
static void Main(string[] args)
{
string str = "0= 1=Full Time 2=Part Time 3=Seasonal 4=Variable";
var separated = str.Split('=');
string code = separated[0].Trim();
var codeAndDescription = new List<Item>();
foreach (var sep in separated.Skip(1).Take(separated.Length - 2))
{
int lastSpace = sep.Trim().LastIndexOf(' ');
var description = lastSpace != -1 ? sep.Substring(0, lastSpace).Trim(): "" ;
codeAndDescription.Add(new Item { Code=code,Description=description });
code = sep.Substring(lastSpace + 1).Trim();
}
codeAndDescription.Add(new Item { Code = code, Description = separated.Last() });
foreach (var kvp in codeAndDescription)
{
Console.WriteLine("Code={0} Description={1}", kvp.Code, kvp.Description);
}
Console.ReadLine();
}
}

How to get the Split value from collection [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have the following key value pair in an array, and am trying to extract and load them into a collection.
The below code is working but it can be optimized using linq:
string _data = "Website=url:www.site1.com,isdefault:true,url:www.site2.com,isdefault:true";
List<WebSiteAddress> _websiteList = new List<WebSiteAddress>() ;
WebSiteAddress _website = new WebSiteAddress();
string[] _websiteData = _divider[1].Split('=');
string[] _WebsiteKeyValuePair = _websiteData[1].Split(',');
for (int j = 0; j < _WebsiteKeyValuePair.Length; j++)
{
string key = _WebsiteKeyValuePair[j].Split(':')[0];
string value = _WebsiteKeyValuePair[j].Split(':')[1];
if (key.ToLower() == "url")
{
_initWebsite.Url = value;
}
else if (key.ToLower() == "isdefault")
{
_website.IsDefault = Convert.ToBoolean(value);
_websiteList.Add(_website);
}
}
You can do something like:
string _data = "Website=url:www.site1.com,isdefault:true,url:www.site2.com,isdefault:true";
List<WebSiteAddress> _websiteList = _data
.Split(new string[]{"url:"}, StringSplitOptions.RemoveEmptyEntries)
.Select(site => site.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries))
.Where(site => site.Length > 1)
.Select(site => new WebSiteAddress { Url = site[0], IsDefault = site[1].ToLower().Replace("isdefault:", "") == "true"})
.ToList();

using HtmlAgilityPack [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a problem HtmlAgilityPack, I would like the following image. but it does not coincide with the lines. What can I do?
HtmlWeb web = new HtmlWeb();
web.OverrideEncoding = Encoding.GetEncoding("windows-1254");
HtmlAgilityPack.HtmlDocument doc = web.Load("http://www.yerelnet.org.tr/belediyeler/belediye.php?belediyeid=129531");
var nufus = doc.DocumentNode.SelectNodes("/html/body/center/table/tr/td[2]/table/tr[2]/td[2]/table/tr[2]/td/table/tr/td/table[5]/tr/td[2]/table/tr/td[3]/table[2]");
string str = String.Empty;
string line = String.Empty;
if (nufus != null)
{
for (int i = 0; i < nufus.Count; i++)
{
str += nufus[i].InnerText.Replace(" ", "").Replace("\t", "").Replace("Nüfus Bilgileri", "");
string[] s = str.Split('\n');
for (int x = 10; x < s.Count(); x++)
{
if (s[x] != String.Empty && s[x] != " ")
{
lnufus.Add(s[x].ToString());
lnufus.Add(s[x].ToString());
lnufus.Add(s[x].ToString());
lnufus.Add(s[x].ToString());
}
}
}
}
dataGridView1.DataSource = lnufus.GroupBy(x => x).Select(g => new
{
Yıl = g.Key, Toplam = g.Key, Kadin = g.Key, Erkek = g.Key
}).ToList();
No need for that strange xpath query. This should work
var nufus = doc.DocumentNode.SelectNodes("//table[#class='belediyeler']/tr")
.Skip(1)
.Select(tr => tr.Elements("td").Select(td => td.InnerText).ToList())
.Select(td => new { Yil = td[0], Toplam = td[1], Kadin = td[2], Erkek = td[3] })
.ToList();
dataGridView1.DataSource = nufus;

transforming to linq [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Is it possible to transform following code to Linq that it will look like little bit more nicely
foreach (var entry in bottleneck.Item2)
{
if(entry.ChangeoverTime > 0)
{
avarangechangeOverTimes += entry.ChangeoverTime;
++counter;
}
if (entry.ChangeoverTime > maxchangeOverTimes)
{
maxchangeOverTimes = entry.ChangeoverTime;
}
changeovertime.ChangeoverTimes.Add
(
new ChangeOverDateValue
{
ChangeoverValue = entry.ChangeoverTime,
Color = ChangeOverTimeToColor(entry.ChangeoverTime),
StartTime = entry.StartTime
}
);
}
If the number of entries in bottleneck.Item2 isn't huge, you could achieve the same using these three statements:
var maxChangeOverTime = bottleneck.Item2.Max(x => x.ChangeoverTime);
var averageChangeOverTime = bottleneck.Item2.Average(x => x.ChangeoverTime);
var result
= bottleneck.Item2
.Select(x => new ChangeOverDateValue
{
ChangeoverValue = x.ChangeoverTime,
Color = ChangeOverTimeToColor(x.ChangeoverTime),
StartTime = x.StartTime
});
changeovertime.ChangeoverTimes.AddRange(result);
Please note that this will enumerate bottleneck.Item2 three times instead of one time with your current code.
I think that you can only change the external foreach:
bottleneck.Items2.ToList().Foreach(entry =>
{
// your code
});
bottleneck.Item2.where(entry => entry.ChangeoverTime).ToList().Foreach(entry => {
avarangechangeOverTimes += entry.ChangeoverTime;
++counter;
});
maxchangeOverTimes = bottleneck.Item2.max=(entry => entry.ChangeoverTime);
changeovertime.ChangeoverTimes.AddAll(bottleneck.Item2.select(entry => new new ChangeOverDateValue
{
ChangeoverValue = entry.ChangeoverTime,
Color = ChangeOverTimeToColor(entry.ChangeoverTime),
StartTime = entry.StartTime
}));
this is all i can come up with without having more info or my development envirment with me
Maybe...
var avarangechangeOverTimes = bottleneck.Item2
.Where(entry => entry.ChangeOverTime > 0)
.Sum(entry => entry.ChangeOverTime);
var maxchangeOverTimes = bottleneck.Item2
.Max(entry => entry.ChangeOverTime);
bottleneck.Item2.ToList()
.ForEach(entry => changeovertime.ChangeoverTimes.Add
(
new ChangeOverDateValue {
ChangeoverValue = entry.ChangeoverTime,
Color = ChangeOverTimeToColor(entry.ChangeoverTime),
StartTime = entry.StartTime
}
)
);
Try this:
var averagechangeOverTimes = bottleneck.Item2
.Where(entry => entry.ChangeoverTime > 0)
.Sum(entry => entry.ChangeoverTime);
counter = bottleneck.Item2.Count(entry => entry.ChangeoverTime > 0);
var maxchangeOverTimes = bottleneck.Item2.Max(entry => entry.ChangeoverTimes);
changeovertime.ChangeoverTime.Add(bottleneck.Item2
.Select(entry => new ChangeOverDateValue{
ChangeoverValue = entry.ChangeoverTime,
Color = ChangeOverTimeToColor(entry.ChangeoverTime),
StartTime = entry.StartTime
});

Categories