The sum of the numbers at the beginning of the line - linq

I have a file : site.log
19 www.mysite.org
300 cod.mysite.org
100 www.newfile.com
199 py.mysite.org
45 python.mysite.org/als
45 mysite.org/als/4/d
I would like to go through all the poems containing the string mysite.org and get the number from the beginning of the text and sum all numbers in front of the given text
File.ReadLines(filePath).Where(x => x.Contains("mysite.org")).SelectMany(...));

You are close. After the Where use Select to project only the beginning of the line:
var result = File.ReadLines(filePath)
.Where(x => x.Contains("mysite.org"))
.Select(x => int.Parse(x.Split()[0]))
.Sum();
Notice that the parsing to int might fail of the prefix is not an integer. You can use TryParse instead. If you will want so you can have a look here: https://stackoverflow.com/a/46150189/6400526

I Split by a space and TryParse first value, if success, I take this value, if not, I take 0
var result = File.ReadLines("")
.Where(x => x.Contains("mysite.org"))
.Select(x => {int temp; return int.TryParse(x.Split(' ')[0], out temp) ? temp : 0;})
.Sum();;

Related

Removing last characters in a string with LINQ

I wanna read a file that eventually will be a matrix but I am bugged about a detail with this code below.
Text file looks like this:
[[15,7,18,11,19,10,14,16,8,2,3,6,5,1,17,12,9,4,13
[17,15,9,8,11,13,7,6,5,1,3,16,12,19,10,2,4,14,18],
[...],
[...]] // Ignore the new lines, in my text file is one single line. I did multiple lines here for readability
So the problem is that it ends with ]] and the end I get two empty list entries which is really bugging me. I wonder if I can remove them during projection, I tried using SkipLast() but the result empty. Any ideas?
var readFile = File.ReadLines("RawTestcases.txt")
.Select(x => x.Replace("[", string.Empty)
.Split("]"))
.ToList();
Ok I actually just put the ]] on a new line and did a SkipLast(1) before projection, but can I do it if is one line?
That looks like Json, so use the right tool:
string file = File.ReadAllText("RawTestcases.txt");
string[][] matrix = JsonConvert.DeserializeObject<string[][]>(file)
.Where(array => array.Length > 0)
.ToArray();
If you need them as integers you can directly use the right type:
int[][] matrix = JsonConvert.DeserializeObject<int[][]>(file)
.Where(array => array.Length > 0)
.ToArray();

How to use Linq Aggregate Query to print line sequence number alongwith some data from the List<string>?

I have a simple List like
List<string> Test=new List<string>() {"A","B","C"}
I am using a simple Linq.Aggregate as under to get a string from the elements of this List as under:-
string Output= Test.Aggregate((First, Next) => First + "\r\n" + Next);
This gives me the result like(new line separated):
A
B
C
However,i want result with a sequence number on each line,ie like this:-
1)A
2)B
3)C
How do i do this using linq?
Select has an overload that will give you the index of the element to work with so you could do Select((x,i)=>String.Format("{0}){1}", i+1,x)). Or in full:
string output= Test.Select((x,i)=>String.Format("{0}){1}", i+1,x)).Aggregate((First, Next) => First + "\r\n" + Next);
One thing worth mentioning though is that string concatenation in a loop (and in the Aggregate counts as in a loop) is generally considered a bad idea for performance reasons. You should consider using alternative methods such as a StringBuilder:
string output = Test
.Aggregate (new StringBuilder(), (sb, x) => sb.AppendFormat("{0}){1}\r\n", lineCount++, x))
.ToString();
I wouldn't use Aggregate here, just a Select to get the index and join the resulting list back together to make a single string, for example:
var output = string.Join("\r\n",
Test.Select((s, index) => $"{index+1}){s}"));

Range of doubles in Swift

I am currently writing a Swift application and parts of it require making sure certain user inputs add up to a specified value.
A simplified example:
Through program interaction, the user has specified that totalValue = 67 and that turns = 2. This means that in two inputs, the user will have to provide two values that add up to 67.
So lets say on turn 1 the user enters 32, and then on turn 2 he enters 35, this would be valid because 32 + 35 = 67.
This all works fine, but the moment we verge into more than one decimal place, the program cannot add the numbers correctly. For example, if totalValue = 67 and then on turn 1 the user enters 66.95 and then on turn 2 he enters .05 the program will return that this is an error despite the fact that
66.95 + .05 = 67. This problem does not happen with one decimal place or less (something like turn 1 = 55.5 and turn 2 = 11.5 works fine), only for two decimal spots and beyond. I am storing the values as doubles. Thanks in advance
Some example code:
var totalWeights = 67
var input = Double(myTextField.text.bridgeToObjectiveC().doubleValue)
/*Each turn is for a button click*/
/*For turn 1*/
if inputValid == true && turn == 1 && input < totalWeights
{
myArray[0] = input
}
else
{
//show error string
}
/*For turn 2*/
if inputValid == true && turn == 2 && input == (totalWeights - myArray[0])
{
myArray[1] = input
}
else
{
//show error string
}
If you want exact values from floating point then the float/double types will not work, as they are only ever approximations of exact numbers. Look into using the NSDecimalNumber class from within Swift, I'm not sure what the bridging would look like but it should be simple.
Here is an example of how this could work:
var a = 0
for num in numlist {
a += num
}
var result = false
if a == targetnum
result = true
I haven't tested this out, but if numlist is an array of double then it should work for any input that is a valid number.
One problem I just realized is that there is an issue with doing an equals with doubles, as rounding will cause problems for you. I am not going to show it, but if, while reading in the inputs you keep track of how many numbers to the right of the decimal place, then multiply all of the values by that number of tens, so 66.95 * 100 to get it all as an integer, then add, then do the comparison, after multiplying the targetnum by the same value (100).
Unfortunately there is no ideal solution to this. We must use approximation type comparison.
For example, instead of checking:
if val1 == val2
we must try something like:
if val1 > (val2 - .0005) && val1 < (val2 + .0005)

VB Console - how to get multiple input in the same line, split and store to list

Say i want to get all the numbers a user inputs in the console.
15,30 45
then I want to then split the 'string' of numbers into different substrings and store it into an array of string or list of type string. Also i want to get the max min avg and total.
Should i store the substring in a array or generic list? I prefer to store it in a list so that i can get the avg and total using list.avg and list.sum
In order to get max min avg and sum, should i convert each element into an integer or convert the whole list to another type? If so, how do i convert?
EDIT: Is there any way to let the user edit the numbers if somehow he mixed a letter or symbol?
First, you can also get the avarage or sum if its a int[] instead of List<int> since Enumerable.Sum or Enumerable.Average takes an IEnumerable<T>. So the decision depends on if you need to modify the collection afterwards. Do you want to add or remove items from it later? Then use a generic List<T>.
string input = "15,30 45";
int i = int.MinValue;
List<int> result = input.Split(new[]{' ', ','}, StringSplitOptions.RemoveEmptyEntries)
.Where(str => int.TryParse(str, out i))
.Select(str => i)
.ToList();
double avg = result.Average();
int sum = result.Sum();
You could try with this code
void Main()
{
double temp;
List<double> input = new List<double>();
string line = Console.ReadLine();
string[] parts = line.Split(' ');
foreach(string p in parts)
{
if(double.TryParse(p, out temp))
input.Add(temp);
}
double sum = input.Sum();
Console.WriteLine(sum);
}
Here I get the input from the Console.ReadLine and split the line at the space separator. Every line subpart is converted to a double value (only if it is possible to convert to a double according to your locale settings) and added to a List<double> . At this point is really simple to obtain the information you need (IEnumerable.Sum, IEnumerable.Average, etc..)

Not equal/not contains operation in lambda expressions

My query is some thing like:
var subQuery = contacts_requests.Where(i => i.requests_usr_id >= 1).Select
(i => i.Usr_contacts_requests_from_usr_id ).ToArray();
var query = biographic_details.Join(profiles_companies, i => i.usr_id, j => j.company_usr_id,
(i,j)=>new{
Usr_bio_usr_id }).where(p=>subQuery.Contains(i.company_usr_id)).ToArray();
I want notcontains operation in place of contains, how can I implement that?
Instead of
p => subQuery.Contains(i.company_usr_id)
use
p => !subQuery.Contains(i.company_usr_id)
Note the ! before the method call. The ! operator (aka Logical negation operator) just negates the result of the following expression. So Contains becomes Not Contains.
To achieve not contains you can use !subQuery.Contains(i.company_usr_id).

Resources