I have mssql table as the given image. I want to know how can I return rows from the table tblSpace that the sum of "Available" rows is greater than or equal to given value using Linq. Also there is a order of filling from 1 to 5. Thanks
Table capture and data:> tblSpace
What I've tried so far
1). If I pass 9,000 as value it should return only Vienguard row (9,000 < 10,000)
2). If I pass 23,000 as value it should return both Vienguard and Halestorm rows (23,000 < 10,000+15,000)
3). if I pass 35,000 as value it should return Vienguard, Halestorm and Quarts rows (35,000 < 10,000+15,000+20,000)
Alright so I think you need something like this?
var sum = 0;
var result = tblSpace.OrderBy(x => x.Available).TakeWhile(x => (sum += x.Available) <= value).ToList();
EDIT
In case you want an extra value if it exceeds you add
var result = tblSpace.OrderBy(x => x.Available).TakeWhile(x => (sum += x.Available) - x.Available < value).ToList();
Related
I load data that has positive and negative values like 0.0012, -0.00034 and so on. How I want to find max values from the data? i refer this website but error link
double max = 0;
for (int i = 1; i <= dataGridView1.Rows.Count - 1; i++)
{
if (max < double.Parse(dataGridView1.Rows[i].Cells[1].Value.ToString()))
{
max = double.Parse(dataGridView1.Rows[i].Cells[1].Value.ToString());
}
}
textBoxMax.Text = max.ToString();
What should i change in my code to get the max. value? I want to display them in the textBox.
On the assumption that you are populating your DataGridView from an underlying DataTable (I appreciate this might be a big assumption), you can simply get a max of the column using Linq:
var maxDouble = dataTable.AsEnumerable().Select(row => row[1]).Max();
I am trying to use Datatable Select but I am getting incorrect data
double marks = 5;
DataRow[] result = dsGrades.Tables[0].Select("Convert(MarksFrom, 'System.Decimal') >=" + marks + " And " + marks + "<= Convert(MarksTo, 'System.Decimal') ");
dsGrades contains below data,
when 'marks' contain '5.0', I am expecting row where MarksFrom = 5.0 and MarksTo = 5.9, as 5.0 falls in this range, but here it is returning 5 rows.
Whats wrong with datatable select? Any help is appreciated.
If would make sense to change your DataColumn types to double, however even with decimal you don't need a conversion inside the expression.
Note in your provided example, your constraint appears to be backwards. You're specifying that you want MarksFrom greater or equal to the passed in amount, which won't return a single row in the range you want.
This should return a single row for any mark passed in:
double marks = 5.0;
DataRow[] result = dsGrades.Tables[0].Select($"{marks} >= MarksFrom AND {marks} <= MarksTo");
Also since you're always only expecting a single match, you could change this to:
DataRow match = table.Select($"{marks} >= MarksFrom AND {marks} <= MarksTo").SingleOrDefault();
SingleOrDefault will throw an InvalidOperationException if more than one result is returned, which may be the desired outcome in this case.
You can do it like this:
double marks = 5.0;
decimal newMarks = Convert.ToDecimal(marks);
var result =
dsGrades.Tables[0]
.AsEnumerable()
.Where( dr => dr.Field<decimal>( "MarksFrom" ) >= newMarks
&& dr.Field<decimal>( "MarksTo" ) < newMarks + 1);
This could be the solution:
var result = dsGrades.Tables[0].Select("Convert(MarksFrom, 'System.Decimal') >=" + newMarks + " And Convert(MarksTo, 'System.Decimal') < " newMarks + 1);
From my comment on question explaining problem:
Getting all the rows where MarksFrom is above 5 will return the first 5 visible rows in table, checking the second condition for these 5 rows and 5.0 is less than or equal to MarksTo in each of the rows so this would evaluate true for these rows. Therefore grabbing 5 rows
Needs to do casting from datatable as below:
DataRow[] drGrdPercntl = dt_GrdPercntil.Select($"{SubjVal} >= Convert(MarksFrom, 'System.Decimal') AND {SubjVal} <= Convert(MarksTo, 'System.Decimal')");
I have a datagrid where a user will input heights in inches then feet and I want to capture the tallest people (based off feet only). I have tried the below syntax, but I get a compile error of:
Non invocable member 'DataGridViewRow.Cells can not be used like a method
This is my syntax - what would be the appropriate way to get the max value of column 1 in my datagrid?
double MaxVal = 0;
foreach (DataGridViewRow row in HeightGrid.Rows)
{
if (row.Cells(1).Value > MaxVal)
{
MaxVal = row.Cells(1).Value;
}
}
To get the max:
MaxVal = dataGridView.Rows.Cast<DataGridViewRow>()
.Max(r => Convert.ToDouble(r.Cells[1].Value));
where Cells[1] denotes the second column.
To your second query:
var biggestRow = dataGridView.Rows.Cast<DataGridViewRow>()
.Aggregate((r1,r2) => Convert.ToDouble(r1.Cells[1].Value) > Convert.ToDouble(r2.Cells[1].Value) ? r1 : r2);
This should give you the row with the biggest value in your second column. From there, you can extract the first and second cells.
It means that Cells is a property, not a method, and as such should be accessed as DataGridViewRow.Cells, not DataGridViewRow.Cells().
Please i am given a task to return an indexes from a 2d array that is frequently updating. Actually is an assignment on the 2048 game . When ever, a random numb is added, i want it added randomly to the free/empty tiles as it should be. Thats where the array value is 0 in my case.
private static int[][] addTile()
{
rd = new Random();
int px, py;
px = rd.Next(0, 4);
py = rd.Next(0, 4);
List<int> availableInd = randPosition(py);
int r = rd.Next(0, availableInd.Count);
int newPx = availableInd[0];
if (Tiles[py][newPx] == 0)
{
Tiles[py][newPx] = rd.Next(0, 20) == 0 ? rd.Next(0, 15) == 0 ? 8 : 4 : 2;
}
else
{
py = py; // I put a break here
}
}
My randPosition() method loks like the fflg;
public static List<int> randPosition(int num)
{
List<int> indexes = new List<int>();
// var emptyTiles = arr.Where(x => x == 0).ToList();
indexes = Tiles[num].Select((s, index) => new { s, index })
.Where(x => x.s == 0)
.Select(x => x.index)
.ToList();
if (indexes.Count > 0)
return indexes;
//Incase The above fails. I would seach row by row
//for an empty tile
for (int c = 0; c < Tiles.Count(); c++)
{
indexes = Tiles[c].Select((s, index) => new { s, index })
.Where(x => x.s == 0)
.Select(x => x.index)
.ToList();
if (indexes.Count > 0)
break;
}
return indexes;
}
First i ramdomly generate my y-axis , i then pass it to the randPosition to check if there exist an empty cell in the said axis. If there are , get the indexes of the cells. IF there are not, i then perform an advance row by row search below to make sure only empty tiles are returned. However, when i put the break at the else of the first method, i realized still occupied tiles/cells are return as empty. I tried alot of manipulations yet to no avail. please where do i go wrong ? How do i best handle this ? Any help suggestion or alternative would highly be appreciated. Thank you
This is somewhat of a guess, but I think you have a logic error:
randPosition(num) is supposed to return the "empty" cells in row num. If it does not find any, it searches row-by-row until it does find an empty cell.
The problem is, the caller doesn't know if the original search failed. It's entirely possible that the indices returned represent cells of a completely different row than was asked for. That may be why you see "occupied" cells returned as "empty".
Here's an analogy:
You're taking a trip to New York. You go to the airport to book a flight (I know, no one does this anymore). You ask for all empty seats on row 7 (because you like row 7). The Customer Service Agent looks up row 7 and finds that there are no empty seats. Instead of telling you that, she instead start looking through all other rows and finds an empty seat (C) on row 15. So she tells you that "Seat C is empty". The problem is, you think she's talking about row 7! You have no indication that row 7 was full or which row she's referring to.
Either the caller needs to iterate through other rows (so that it knows which row the empty cells are on), or the method needs to have some sort of feedback that indicates which row the empty cells are on.
i started learning C# and programming a few months ago and have some problems. The idea here is we create a 2 dimensional array (the number of rows / columns are added by the user), the numbers need to be between 1 and 10.
Then when the array is created the number sequence ( 3-5-7-9-11 etc) is started in the first and finishes in the last column. The rest of the numbers in the columns are added via keyboard by the user starting with the first row (ignoring column 1 and the last column cause we have that added).
The questions are :
What will be the best way to check if the numbers of rows/columns are between 1 and 10? (I was thinking of IF-else but isn't there a better way ?)
How will i make it so that the number sequence 3-5-7 etc is started in the first and finishes in the last column?
Yeah i feel lost.
Where i am at the moment :
Console.WriteLine("Add row value of 1-10");
string s1
s1 = Console.ReadLine();
int k = int.Parse(s1);
Console.WriteLine("Add column value of 1-10");
string s2;
s2 = Console.ReadLine();
int p = int.Parse(s2);
int[,] M = new int[k, p];
Example : we added k(row) & p(coulmn) value of 4.So the array should look like :
3 x x 11
5 x x 13
7 x x 15
9 x x 17
Then the X's should be added again manually without overwriting the existing numbers .The value of the numbers doesnt matter.
So... If I get it right you want to ask user the "length and width" of dynamical 2d array?
To check if entered number is between 1 and 10 there's only 1 method:
int [,] M;
if (k >= 1 && k <= 10 && p >= 1 && p <= 10)
{
M = new int[k,p];
}
And better is to do int.TryParse() for case if user enters characters there instead of numbers, or else you can easily get an Exception.
Filling with numbers:
int num = 3;
for (int i = 0; i < k; ++i)
{
M[i,0] = num;
num+=2;
}
for (int i = 0; i < k; ++i)
{
M[i,p] = num;
num+=2;
}
This adds numbers in 1st and last column in each row. After that to fill other cells manually you check every cell thet it is not in firs or last column.
I hope I understood you correctly. Provided code may be simplified, but provided in such way for better understanding.
if(k>0 && k<11 && p>0 && p<11)
{
int i;
int M[,] = new int[k,p];
for (i=0;i<k;i++)
{
M[i,0]=i*2+3;
M[i,p-1]=(i+k)*2+3;
}
}