I have a CSV file that has numerous rows and columns. All rows will be distinct except for the first column which will be an account name. There are for example ten different account names that have about 100 rows for each account name . So for each account name that appears I need to get a sum for all the proceeding columns in that row.
So a csv file like this:
Smith, 10, 5, 9
Smith, 9, 5, 6
Jones, 10, 5, 7
jones, 9, 6, 5
Needs to be written to another file like this:
Smith, 19, 19, 15
Jones, 19, 11, 12
Been trying all morning using either an array or a Dictionary to do this, but I can't seem to logically get this done.
static void Main(string[] args)
{
String path = #"C:\Users\jhochbau\documents\visual studio 2015\Projects\CsvReader\CsvReader\Position_2016_02_25.0415.csv";
string[] lines = File.ReadAllLines(path);
foreach(string line in lines)
{
string[] parsedLine = line.Split(',');
//for each iteration through the loop where string[0] is already existing
//I want to have sum = sum + string[1]
}
Console.Read();
}
I also tried using a dictionary for this but ended up only grabbing the row when a distinct name came up.
//To add account as key and each line as value
foreach(var s in data)
{
string[] temp = s.Split(',');
//Adds key of account into dictionary, full string line as value.
dictionary.Add(temp[0], temp);
foreach (KeyValuePair<string, string[]> accountKeyValuePair in dictionary)
{
Console.WriteLine("Account = {}", accountKeyValuePair.Key); //Additional information: Input string was not in a correct format.
}
}
Looking for either a link to a similar example, or maybe a gentle nudge in the right logical direction. I don't really want the answer coded for me.
Check this:
public static void Run()
{
var lines = new List<string>() {
"Smith, 10, 5, 9",
"Smith, 9, 5, 6",
"Jones, 10, 5, 7",
"Jones, 9, 6, 5"
};
var aList = from l in lines
select new { Name = l.Split(',')[0], Value1 = Convert.ToInt32(l.Split(',')[1]), Value2 = Convert.ToInt32(l.Split(',')[2]), Value3 = Convert.ToInt32(l.Split(',')[3]) };
var vList = from a in aList
group a by a.Name into g
select new { Name = g.Key, Value1Sum = g.Sum(a => a.Value1), Value2Sum = g.Sum(a => a.Value2), Value3Sum = g.Sum(a => a.Value3) };
foreach (var v in vList)
Console.WriteLine("{0} {1} {2} {3}", v.Name, v.Value1Sum, v.Value2Sum, v.Value3Sum);
}
Related
I have two arrays whose elements are one to one mapped.
string [] denom = new string[] { EUR, GBP, EUR, USD, USD};
int [] count = new int[] { 1, 3, 4, 7, 8};
EUR - 1
GBP - 3
EUR - 4
USD - 7
USD - 8
I want to get an output into an array by summing the count based on the denom
So, EUR - 5 (1 +4), GBP - 3, USD - 15 (7+8)
The output array should have values like {5, 3 , 15}
We have a logic to remap the final count with Denoms (i.e, EUR, GBP, USD)
We want the logic in C#.net
To achieve desired output below code sample will help you.
string[] denom = new string[] { "EUR", "GBP", "EUR", "USD", "USD" };
int[] count = new int[] { 1, 3, 4, 7, 8 };
//Create dictionary object to manage group by denom
Dictionary<string, int> dct = new Dictionary<string, int>();
//Iterate and sum group by denom
for (int i = 0; i < denom.Length; i++)
{
if (!dct.Keys.Contains(denom[i]))
dct[denom[i]] = 0;
dct[denom[i]] += count[i];
}
//Print output
foreach (KeyValuePair<string, int> kpVal in dct)
Console.WriteLine(kpVal.Key + "=" + kpVal.Value);
dct.Clear();
See the output printed below.
You could simply create a map and keep up the sum as below:
Map<String, Integer> currencyValueMap = new HashMap<>();
for (int i=0; i<denom.length; i++) {
currencyValueMap.put(denom[i], (k, v) v == null ? count[i] : count[i] + v);
}
At the end, you would be left with currency name as key while total value as a value against that particular key.
How find if any list in list of list contains all elements in another list?
Something like list list .contains(list), where list(list) is stanjaDKA, and list is tmpzaNormalanPrijelaz, and all list members are of type int?
I tried this but I get to much states in stanjaDKA at the end.
int indeks=stanjaDKA.FindIndex(x=>x.Equals(tmpzaNormalanPrijelaz));
if (indeks==-1 && tmpzaNormalanPrijelaz.Count>0)
{
stanjaDKA.Add(tmpzaNormalanPrijelaz);
}
How find if any X in list of X
Use LINQ's Any:
bool anyXInListOfX = myListOfX(x => someConditionOnX);
list contains all elements in another list
If you're not concerned about duplicate elements (i.e. if you're happy that {1} contains all the elements in {1, 1}), you can use LINQ's Except and check there is nothing left:
bool firstListContainsAllElementsInSecondList =
!mySecondList.Except(myFirstList).Any();
However, "any list contains all elements" is equivalent to "all lists don't contain all elements", and the don't cancels with the ! in the above, so in your case I'd do something like
if (stanjaDKA.All(l => tmpzaNormalanPrijelaz.Except(l).Any()))
{
stanjaDKA.Add(tmpzaNormalanPrijelaz);
}
This reads as "if all the lists in stanjaDKA are each missing at least one element in tmpzaNormalanPrijelaz, add tmpzaNormalanPrijelaz to stanjaDKA".
depending on what you are really want this will help you to do the mayor stuff
// Sample List<List<int>>
var listList = new List<List<int>>();
listList.Add(new List<int>() { 0, 1, 2, 3, 4 });
listList.Add(new List<int>() { 0, 1, 2, 3, 4 });
listList.Add(new List<int>() { 1, 1, 2, 3, 4 });
listList.Add(new List<int>() { 1, 1, 1, 1, 1 });
listList.Add(new List<int>() { 5, 6, 7, 8, 9 });
// the List you are seaching for
var searchList = new List<int>() { 10 };
foreach(List<int> list in listList)
{
var newList =list.Intersect(searchList);
if (newList.Count() == searchList.Count)
{
string elements = "";
foreach (int item in newList)
{
elements += item + " ";
}
Console.WriteLine(elements);
}
}
Console.ReadLine();
you should also take a look at this Link maybe you need it
I want to find the top 3 maximum repeated numbers in a Integer array?
Below is the piece of code which I have tried but I couldn't find the desired result:
static void Main(string[] args)
{
int[,] numbers = {
{1, 2, 0, 6 },
{5, 6, 7, 0 },
{9, 3, 6, 2 },
{6, 4, 8, 1 }
};
int count = 0;
List<int> checkedNumbers = new List<int>();
foreach (int t in numbers)
{
if (!checkedNumbers.Contains(t))
{
foreach (int m in numbers)
{
if (m == t)
{
count++;
}
}
Console.WriteLine("Number {0} is Repeated {1} Times ", t, count);
count = 0;
checkedNumbers.Add(t);
}
}
Console.ReadLine();
}
You can use GroupBy from LINQ then OrderByDescending based on count in each group:
var result = list.GroupBy(i => i)
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.Take(3);
Edit: With your code, you can use OfType to flatten your matrix then use the code above:
int[,] numbers = {
{1, 2, 0, 6 },
{5, 6, 7, 0 },
{9, 3, 6, 2 },
{6, 4, 8, 1 }
};
var list = numbers.OfType<int>();
int[] numbers = {1, 2, 3, 5, 6, 32, 2, 4, 42, 2, 4, 4, 5, 6, 3, 4};
var counts = new Dictionary<int, int>();
foreach (var number in numbers)
{
counts[number] = counts[number] + 1;
}
var top3 = counts.OrderByDescending(x => x.Value).Select(x => x.Key).Take(3);
Hint:
You can do this with the help of LINQ.
This is the code to find most frequest occuring element:-
List<int> list = new List<int>() { 1,1,2,2,3,4,5 };
// group by value and count frequency
var query = from i in list
group i by i into g
select new {g.Key, Count = g.Count()};
// compute the maximum frequency
int frequency = query.Max(g => g.Count);
// find the values with that frequency
IEnumerable<int> modes = query
.Where(g => g.Count == frequency)
.Select(g => g.Key);
// dump to console
foreach(var mode in modes) {
Console.WriteLine(mode);
}
In the same manner you can find the other two also.
I see that none of the existing answers provide an explanation, so I will try to explain.
What you need to do is to count how many times each item appears in the array. To do that, there are various methods (dictionaries, linq etc). Probably it would be easiest to use a dictionary which contains the number, and how may times it appeared:
int numbers[] = {1, 3, 6, 10, 9, 3, 3, 1, 10} ;
Dictionary<int, int> dic = new Dictionary<int, int>();
Now iterate through every element in numbers, and add it to the dictionary. If it was already added, simply increase the count value.
foreach (var i in numbers)
{
dic[i]++; // Same as dic[i] = dic[i]+1;
}
The dictionary will automatically adds a new item if it doesn't exist, so we can simply do dic[i]++;
Next, we need to get the highest 3 values. Again, there are many ways to do this, but the easiest one would be to sort it.
var sorted_dic = dic.OrderByDescending(x => x.Value);
Now the first 3 items in sorted_dic are going to be the 3 values you are looking for.
There are various methods to get only these 3, for example using the Take method:
var first_3 = sorted_dic.Take(3);
Now you can iterate through these 3 values, and for example print them on the screen:
foreach (var i in first_3)
{
Console.Write("{0} appeared {1} times.", i.Key, i.Value);
}
I have two lists of strings. How do I get the list of distinct values between them or remove the second list elements from the first list?
List<string> list1 = { "see","you","live"}
List<string> list2 = { "see"}
The result should be {"you","live"}.
It looks to me like you need Enumerable.Except():
var differences = list1.Except(list2);
And then you can loop through the differences:
foreach(var difference in differences)
{
// work with each individual string here.
}
If you want to get items from the first list except items in the second list, use
list1.Except(list2)
If you want to get items that are in the first list or in the second list, but not both, you can use
list1.Except(list2).Concat(list2.Except(list1))
This is the good way I find unique....
Unique from two list
var A = new List<int>() { 1,2,3,4 };
var B = new List<int>() { 1, 5, 6, 7 };
var a= A.Except(B).ToList();
// outputs List<int>(2) { 2,3,4 }
var b= B.Except(A).ToList();
// outputs List<int>(2) { 5,6,7 }
var abint= B.Intersect(A).ToList();
// outputs List<int>(2) { 1 }
here is my answer,
find distinct value's in two int list and assign that vlaues to the third int list.
List<int> list1 = new List <int>() { 1, 2, 3, 4, 5, 6 };
List<int> list2 = new List<int>() { 1, 2, 3, 7, 8, 9 };
List<int> list3 = new List<int>();
var DifferentList1 = list1.Except(list2).Concat(list2.Except(list1));
foreach (var item in DifferentList1)
{
list3.Add(item);
}
foreach (var item in list3)
{
Console.WriteLine("Different Item found in lists are{0}",item);
}
Console.ReadLine();
I have the following arrays:
var original= new int[] { 2, 1, 3 };
var target = new int[] { 1, 3, 4 };
enum Operation {Added,Removed}
I would like to execute a LINQ query that would return the following:
{{2,Removed},{4,Added}}
Limitation: I would like LINQ to perform this very efficiently and avoid and O(n^2) style algorithms.
Perhaps a LINQ solution is not the best option in this case.
This will produce a dictionary with the result that you want.
Dictionary<int, Operation> difference = new Dictionary<int,Operation>();
foreach (int value in original) {
difference.Add(value, Operation.Removed);
}
foreach (int value in target) {
if (difference.ContainsKey(value)) {
difference.Remove(value);
} else {
difference.Add(value, Operation.Added);
}
}
To keep the size of the dictionary down, perhaps it's possible to loop the enumerations in parallell. I'll have a look at that...
Edit:
Here it is:
Dictionary<int, Operation> difference = new Dictionary<int,Operation>();
IEnumerator<int> o = ((IEnumerable<int>)original).GetEnumerator();
IEnumerator<int> t = ((IEnumerable<int>)target).GetEnumerator();
bool oActive=true, tActive=true;
while (oActive || tActive) {
if (oActive && (oActive = o.MoveNext())) {
if (difference.ContainsKey(o.Current)) {
difference.Remove(o.Current);
} else {
difference.Add(o.Current, Operation.Removed);
}
}
if (tActive && (tActive = t.MoveNext())) {
if (difference.ContainsKey(t.Current)) {
difference.Remove(t.Current);
} else {
difference.Add(t.Current, Operation.Added);
}
}
}
Edit2:
I did some performance testing. The first version runs 10%-20% faster, both with sorted lists and randomly ordered lists.
I made lists with numbers from 1 to 100000, randomly skipping 10% of the numbers. On my machine the first version of the code matches the lists in about 16 ms.
enum Operation { Added, Removed, }
static void Main(string[] args)
{
var original = new int[] { 2, 1, 3 };
var target = new int[] { 1, 3, 4 };
var result = original.Except(target)
.Select(i => new { Value = i, Operation = Operation.Removed, })
.Concat(
target.Except(original)
.Select(i => new { Value = i, Operation = Operation.Added, })
);
foreach (var item in result)
Console.WriteLine("{0}, {1}", item.Value, item.Operation);
}
I don't think you can do this with LINQ using only a single pass given the stock LINQ extension methods but but might be able to code a custom extension method that will. Your trade off will likely be the loss of deferred execution. It would be interesting to compare the relative performance of both.
You are out of luck. If, as you stated in the comments, the lists are not sorted you can't compute the difference you seek in a single forward pass. Consider:
{ 1, 2, 3, 4, 5, 6, 7, ...
{ 1, 2, 3, 6, 7, 8, 9, ...
At the point where the first difference in encountered (4 vs. 6) it's impossible for you to determine if you are looking at the removal of 4 & 5 (as would be the case if both lists were monotonically increasing, or the insertion of 6, 7, 8, & 9 as would be the case if the lists continued like so:
{ 1, 2, 3, 4, 5, 6, 7, 8, 9,...
{ 1, 2, 3, 6, 7, 8, 9, 4, 5, 6, 7, 8, 9,...
This will achieve the result in a single pass, however I'm not sure of the complexity of the GroupBy operation.
var original= new int[] { 1, 2, 3 };
var target = new int[] { 1, 3, 4 };
var output = original.Select( i => new { I = i, L = "o" } )
.Concat( target.Select( i => new { I = i, L = "t" } ) )
.GroupBy( i => i.I ).Where( i => i.Count() == 1 )
.Select( i => new { I = i.Key, S = (i.ElementAt( 0 ).L == "o" ? Operation.Removed : Operation.Added) } );