Let's say I have this list:
1
1
1
1
2
2
2
3
I want to narrow it down with C# to a list with a maximum of two same items in a list so it would look like this:
1
1
2
2
3
I used to use 'distinct' like this:
string[] array = System.IO.File.ReadAllLines(#"C:\list.txt");
List<string> list = new List<string>(array);
List<string> distinct = list.Distinct().ToList();
but don't have an idea on how it could bring a max number of same values
You could do it with Linq as follows.
var Groups = Input.GroupBy( i => i );
var Result = Groups.SelectMany( iGroup => iGroup.Take(2) ).ToArray();
Related
I have list of ids like this below
List<int> ids = new List<int>();
and then i have list of lengths which is also integers like this below..
List<int> lengths = new List<int>();
now i need to insert into table using linq query with the data format like this below
ID length
1 1
1 2
1 3
2 1
2 2
2 3
for that i am doing like this
foreach (var item in ids)
{
foreach (var item in lengths)
{
}
}
With the above way i am not able insert the multiple id's in the table .. I am hoping there should be better way to do this..
Could any one please suggest any ideas on this one that would be very grateful to me..
Thanks in advance.
If you wanted to project these 2 lists to a flattened list with LINQ, you could use SelectMany
Projects each element of a sequence to an IEnumerable and flattens
the resulting sequences into one sequence.
// projecting to an anonymous type
var results = ids.SelectMany(id => lengths.Select(length => new {id, length }));
// or projecting to a value tuple
var results = ids.SelectMany(id => lengths.Select(length => (id, length)));
If you really want a single loop, you can loop over the final result length and compute the indexes into each List:
var idsCount = ids.Count;
var lengthsCount = lengths.Count;
var totalCount = idsCount * lengthsCount;
for (int j1 = 0; j1 < totalCount; ++j1) {
var id = ids[j1 / lengthsCount];
var length = lengths[j1 % lengthsCount];
new { id, length }.Dump();
// insert id,length
}
I have (1,2,3) and i want insert in my table:
1-2
2-3
But I want exclude 2-1 and 3-2.
Any help?
First get the cartesian product of the items. Then exclude those with difference more than 1 and first number >= second number. Like this:
List<int> list = new List<int>(){1, 2, 3};
var result = from n1 in list
from n2 in list
select new {n1, n2};
result = result.Where(n=> (n.n1 < n.n2) && (n.n2 - n.n1 == 1)).ToList();
This will give you what you want:
Results
I have two lists in C#.
public List<MyClass> objectList = new List<MyClass>(); // it is filled with MyClass objects
public List<int> numberList = new List<int>(); // it is filled with numbers
The index of numbers in the numberList correspond to object index in the objectList: For example: objectList[0] = o1 and numberList[0] = 3 ;
objectList[1] = o2 and numberList[1] = 5 ...
objectList: |o1 | o2 | o3 | o4 | o5 | ...
numberList: 3 5 6 1 4 ...
I want to sort the numbers in the numberList in ascending order and I want for the objetcs in objectList to move with them:
After sorting:
objectList: |o4 | o1 | o5 | o2 | o3 | ...
numberList: 1 3 4 5 6 ...
In practical use I need this for implementing the Hill climbing algorithm on a N queen problem. In the objectList I store positions of all the queens on the board and in the numberList I store the calculated heuristics for the positions. Then I want to sort the numberList so I get the position with the lowest heuristic value. The goal is to move to the position with the lowest heuristic value.
Transform your object list into a sequence of items paired with their indices:
var pairs = objectList.Select(item, index) => new { item, index };
Now you have something you can use to do an ordering:
var orderedPairs = pairs.OrderBy(pair => numberList[pair.index]);
Now you have an ordered list of pairs. Turn that back into an ordered list of items:
var ordered = orderedPairs.Select(pair => pair.item);
and turn it into a list:
var orderedList = ordered.ToList();
Note that your original lists are not altered. This creates a new list that is in the order you want.
Of course you can do it all in one expression if you like:
objectList = objectList
.Select((item, index) => new { item, index } )
.OrderBy(pair => numberList[pair.index])
.Select(pair => pair.item)
.ToList();
Now, all that said: it sounds like you're doing too much work here because you've chosen the wrong data structure. It sounds to me like your problem needs a min heap implementation of a priority queue, not a pair of lists. Is there some reason why you're not using a priority queue?
I am trying to compare 2 lists and return items that don't match by comparing 3 fields inside those lists. For example
List<Chemical> mList = mresult.ToList(); -- less 5 items
List<Chemical> xList = xresult.ToList(); -- 7 items -- need 2 items back
foreach (var List in xList )
{
if (!(mList .Exists(x => x.MSD_ID == List.MSD_ID)) && !(mList .Exists(y => y.Roman_ID == List.Roman_ID)) && !(mList .Exists(z => z.Source_System_ID == List.Source_System_ID)))
{
Chemical x = new Chemical
{
MSD_ID = List.MSD_ID,
Roman_ID = List.Roman_ID,
Source_System_ID = List.Source_System_ID
};
unmatchedList.Add(x); --need 2 items but returns none
}
}
I really want to know where I am missing it. Thanks all in advance
Include the MoreLinq package from NuGet and use:
List<Chemical> mList = mresult.ToList(); -- less 5 items
List<Chemical> xList = xresult.ToList(); -- 7 items -- need 2 items back
var unmatchedList = xList.ExceptBy(mLlist,x=>new {x.MSG_ID,x.Roman_ID,x.Source_System_ID});
Alternatively, you can implement IEqualityComparer like as shown here: List.Except is not working
If your Chemical class only has those 3 fields, then just:
List<Chemical> mList = mresult.ToList(); -- less 5 items
List<Chemical> xList = xresult.ToList(); -- 7 items -- need 2 items back
var unmatchedList = xList.Except(mLlist);
I have the following query:
var results = from theData in GeometricAverage
group theData by new { study = theData.study, groupNumber = theData.groupNumber, GeoAverage= theData.GeoAverage } into grp
select new
{
study = grp.Key.study,
groupNumber = grp.Key.groupNumber,
TGI = testFunction(grp.Key.GeoAverage, Also here I want to pass in the GeoAverage for only group 1 (but for each individual study))
};
What I want to do is that for each study, there are multiple groups with a GeoAverage figure for each group. The TGI is calculated by passing the GeoAverage figure for each group and the GeoAverage figure for group 1 (on each study) into the testFunction. I can't figure out how to pass in the value just for group 1.
Hope this makes sense.
EDIT: Sample of data:
Study Group GeoAverage
1 1 3
1 2 5
1 3 6
2 1 2
2 2 3
2 3 9
So, for the above data, I would want each GeoAverage figure for each group, to be evaluated against the GeoAverage figure of group 1 within that same study. So if I have say a function:
int foo(int a, int b)
{
return a * b;
}
Using the data above, I would first evaluate study 1, group 1 against itself, so pass in GeoAverage 3 twice and return 9. For Study 1, group 2, pass in group 2 GA at 5, and that studys group1 GA at 3, returning 15.
Have now worked it out. I iterate through a collection of data that I want the value to be stored against and use the following two LINQ queries:
foreach (var data in compoundData)
{
var controlValue = from d in GeometricAverage
where d.study == data.study
where d.groupNumber == "1"
select d.GeoAverage;
var treatmentValue = from l in GeometricAverage
where l.study == data.study
where l.groupNumber == data.groupNumber
select l.GeoAverage;
data.TGI = CalculateTGI(controlValue, treatmentValue);
}