I have two lists that is
List<int> comments ;
List<int> no_checks;
Now i would like to see if all no_checks have comments. So during my processing of data whenever a comment is added am adding its id to comment list and when a no radio is selected am adding its id to no_checks
So a sample output to console has
1.
below should return false;
comment=[12, 13,15]
no_checks = [12,13,15,17 ] //one no has no comment
2
below should return true
comment=[12, 13,15]
no_checks = [12,13 ] //all have comments
So am stuck here
public bool allnoHaveComments(){
var allhave=true;
for(var i=0; i<no_checks.count; i++){
//if one no_checks is not contained in comments allhave=false
}
return allhave;
}
How can i proceed to compare and check to see that id's in no_checks are all contained in comments else if they are not return false
How can i go about this
bool isallnoHaveComments= !no_checks.Except(comment).Any();
This gives you the values in no_checks that aren't in comments
no_checks.Except(comments)
Your problem is basically Check whether an array is a subset of another.
I have used here two for loops, one for comments list and the other for no_checks which is nested inside loop for comments
private bool check_Commentexist(List<int> comments, List<int> no_checks)
{
var j = 0;
var k = 0;
Boolean commentexist = false;
for (var i = 0; i < no_checks.Count; i++)
{
j = no_checks[i];
commentexist = false;
for (var x = 0; x < comments.Count; x++)
{
k = comments[x];
if (j == k) { commentexist = true; break; }
}
//if no match found for atleast on element break the loop
if (commentexist == false) break;
//else if match found the looping continues to check the
//next element in 'no_checks' for a mathcing comment
}
return commentexist;
}
Related
How can i move 3 items from list a to list b, removing those elements from list a at the same time
for (int i = 0; i < NeedToClean.Count; i++)
{
if (!Cleaing.Contains(NeedToClean[i]) && Cleaing.Count != 3)
{
Cleaing.Add(NeedToClean[i]);
break;
}
else
{
NeedToClean.Remove(Cleaing[i]);
}
}
You can remove items from a list that you're iterating over if you iterate (and remove) from the end. This way your index variable is always in range.
for (int i = NeedToClean.Count - 1; i >= 0; i--)
{
if (!Cleaing.Contains(NeedToClean[i]))
{
// Add the item to one array
Cleaing.Add(NeedToClean[i]);
// Remove it from the original array
NeedToClean.RemoveAt(i);
// Quit when we've moved 3 items
if (Cleaning.Count == 3) break;
}
}
I don't know if it can help you, but with the take you can take the first n items of a list, in this way you can copy them and then delete them, in the example below I created a list with 4 elements, I took the first 3 I moved them to empty list and subsequently deleted.
var a = new List<string>() { "Alpha", "Beta", "Gamma", "Delta" };
var b = new List<string>();
b.AddRange(a.Take(3));
a.RemoveRange(0, 3);
List indexes;
for (int i = 0; i < NeedToClean.Count; i++)
{
if(!Cleaing.Contains(NeedToClean[i]) && Cleaing.Count != 3)
{
Cleaing.Add(NeedToClean[i]);
indexes.Add(i);
}
}
while(indexes.Length != 0)
{
int biggest;
foreach(int i in indexes){
biggest = (i > biggest) ? i : biggest;
}
NeedToClean.Remove(Cleaing[biggest]);
}
Now, this may be a bit overcomlicated, and I am not really confortable in cpp, but something like this should work. (Coming form C#)
The reason of that while loop is that we remove indexes from the end of the list/array first, so things don't conflict. Hope it helps and my reputation won't get stomped into the ground :D
i cant seem to get the exit condition right for this
The code for moving and spacing the Array
List<string> route = new List<string>() { "Bmiddle", "Middle", "Tmiddle", "TRight", "Right", "Middle", "Left", "Bleft", "Middle", "Left" };
// this is the correct way the player should follow to be able to exit
List<string> Currentroute = new List<string>();
// each time the player is at a spot it should add it to this list in order to meet the exit condition
string[,] arrayLab = new string[3, 3] { {"Tleft", "TMiddle", "TRight"}, /*0 */
{"Left", "Middle", "Right"}, /*1 */
{"Bleft", "Bmiddle", "Bright"} }; /*2 */
do
{
// here is supposed to be all the controls and spacing to make it look like the array. and the logic
}
while (Currentroute != route)
//The Current route must match the Route in order to meet this exit
}
}
My attempt at solving
i cant seem to add the postion the player is in to the Currentroute list in order to be able to get out,
int a = playerY;
int b = playerX;
foreach (char i in arrayLab[b, a])
{
Currentroute.Add(i.ToString());
Console.WriteLine(i);
}
i tried this but it just spells the position char for char and doesnt save it
I did not understand exactly what you mean, but I prepared a piece of code to navigate the list.
In the end all the elements of the two lists are equal
for (int i = 0; i < route.Count; i++)
{
bool exitloop = false;
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
if (arrayLab[j, k] == route[i])
{
Currentroute.Add(arrayLab[j, k]);
exitloop = true;
break;
}
}
if (exitloop)
break;
}
}
foreach (var item in Currentroute)
{
Console.WriteLine(item);
}
In the first list, change Tmiddle to TMiddle and do not use the while loop. I hope it was useful.
So I have this homework assignment that requires me to assign output to labels after I compare two arrays. My problem is that after I compare the two arrays, the output I assign is wrong. I'm supposed to out 'Y' if at a specific index of the two arrays are equal and 'N' if they're not equal but every time I run the code, it outputs 'Y' to all the labels no matter what. How can I fix what is being outputted after the comparison?
private void evaluateStudentAnswers()
{
/* Use a "for" loop to cycle through the answerKey[] and studentAnswers[] arrays, and compare the answers
* in the two arrays at each index. If they match, then increment the global variable "correctAnswers"
* and assign the value 'Y' to the corresponding index in the correctOrIncorrect[] array. if they
* don't match, then increment the global variable "incorrectAnswers" and assign the value 'N' to the
* corresponding indes in the correctOrIncorrec[] array. These two variables will be used to calculate
* the grade percentage.
*/
for (int i = 0; i < studentAnswers.Length; i++)
{
for(int j = 0; j < answerKey.Length; j++)
{
// I think the indexes below are being checked if they're the same and I need to make sure not just the
//indexes are the same but the values as well
if (studentAnswers[i] == answerKey[j])
{
correctAnswers++;
for(int k = 0; k < correctOrIncorrect.Length; k++)
{
correctOrIncorrect[k] = 'Y';
}
}
else
{
incorrectAnswers++;
for (int k = 0; k < correctOrIncorrect.Length; k++)
{
correctOrIncorrect[k] = 'N';
}
}
}
}
}
I think your code can be simplified quite a lot. assuming there's a 1-1 mapping between studentAnswers and answerKey.
for (int i = 0; i < studentAnswers.Length; i++)
{
var studentAnswer = studentAnswers[i];
var answer = answerKey[i];
if (studentAnswer == answer)
{
++correctAnswers;
correctOrIncorrect[i] = 'Y';
}
else
{
++incorrectAnswers;
correctOrIncorrect[i] = 'N'
}
}
All of the arrays are the same size. So when we loop over each answer the student provided, we know we can find the corresponding correct answer in answerKey. Also, the tracking of correct answers also follows the same pattern, for each studentAnswer, we want to record the correctness in correctOrIncorrect, which corresponds to the particular answer the student provided. As such, we only need to perform a single loop, since the i refers to the appropriate index in all the arrays as we're processing.
If studentAnswers.Length == answerKey.Length == correctOrIncorrect.Length
Then
for (int i = 0; i < studentAnswers.Length; i++)
{
if(studentAnswers[i] == answerKey[j])
{
correctAnswers++;
correctOrIncorrect[k] = 'Y';
}
else
{
incorrectAnswers++;
correctOrIncorrect[k] = 'N';
}
}
Since it is an assignment I wont give an answer :) but since you are stuck I encourage you use the guidance below.
These two are unnecessary in your code
inner for-loop on correctOrIncorrect[]
variable "k", you can use "i" instead for correctOrIncorrect value assignment
Since the arrays have to have the same size/order, you only need to loop through them once. Also I find ternary assignments more clear than if blocks:
Func<bool, int> toInt = (b) => b ? 1 : 0;
for (int i = 0; i < studentAnswers.Length; i++)
{
var studentAnswer = studentAnswers[i];
var answer = answerKey[i];
var isCorrect = studentAnswer == answer;
correctOrIncorrect[i] = isCorrect ? 'Y' : 'N';
correctAnswers = isCorrect ? 1 : 0; // toInt(isCorrect)
incorrectAnswers = !isCorrect ? 1 : 0; // toInt(!isCorrect)
}
}
Or in LINQ (just because it's worth learning, but probably not appropriate for homework):
correctOrIncorrect = answerKey.Zip(studentAnswer, (a,b) => a == b ? "Y" : "N").ToArray();
incorrectAnswers = correctOrIncorrect.Count(x => x == "Y");
...
Basically comparing a string that is entered, and trying to get that position from the array.
If I initialize position to 0 then it returns the position zero of the array, if I initialize to 1 then it gives me the item in slot 1, so it's skipping the compare statement.
I also tried using (custStatus == cardStatus[i])
public static int discount(string []cardStatus, int []pDiscount, string custStatus)
{
int position= 0;
int discount;
for(int i = 0; i < 2; i++)
{
if (string.Equals(custStatus, cardStatus[i]))
position = i;
}
discount = pDiscount[position];
return discount;
}
With your code, there's no way to tell if position = 0 means custStatus was found in your cardStatus array or if no match was made at all and the default value is being used. I'd recommend either using a boolean matchFound variable or setting position = -1 and adding an extra if statement at the end either way. Either:
boolean matchFound = false;
...
if(matchFound)
{
discount = pDiscount[position];
}
or else
int position = -1;
...
if(position >= 0)
{
discount = pDiscount[position];
}
Give this a try:
public static int discount(string[] cardStatus, int[] pDiscount, string custStatus) {
var position = Array.IndexOf(cardStatus, custStatus);
return (position == -1) ? -1 : pDiscount[position];
}
public static int discount(string []cardStatus, int []pDiscount, string custStatus)
{
for(int i = 0; i < Math.Min(cardStatus.Length, pDiscount.Length); i++)
{
if (string.Equals(custStatus, cardStatus[i]))
{
return pDiscount[i];
}
}
return -1;
}
Don't be afraid to return directly from FOR-loop, it is old-school that teaches to have only one return point from method. You can have as many returns as it helps you to keep your code clean and easy to read.
And perhaps it would be better to use the following expression in for-loop as it will guard you from possible different lengths of arrays:
for (int i = 0; i < Math.Min(cardStatus.Length, pDiscount.Length; i++)
This looks ok, even though this is somewhat more straightforward:
for(int i = 0; i < cardStatus.Length; i++)
{
if (custStatus == cardStatus[i])
{
position = i;
break;
}
}
Given your question it appears to be the case that all cardStatus[i] match custStatus - did you check the input?
Also given your code what happens if there is no match? Currently you would return pDiscount[0] - that doesn't seem to be correct.
I have a function that takes in a roleID(as an int), and compares it to a multidimensional array to see if that array contains that roleID. if it does, it sets a bool to true and breaks. if it doesn't, the loop never exits. I'm hoping this is something stupid that I'm overlooking, but I've had a few different people look it over now.
The size of the userRoles array that I am testing with right now is 3. I can print userRoles.GetLength(0) and it says 3, and that matches whats in the database.
here's the code:
public bool IsInRole(int roleID)
{
bool inRole = false;
int i = userRoles.GetLength(0);
for (int j = 0; j < i; j++)
{
if (Convert.ToInt32(userRoles[j, 0]) == roleID)
{
inRole = true;
break;
}
}
return inRole;
}
TIA,
Chris
Are you sure that you're not misdiagnosing the symptom, and that it really is getting stuck in the loop? The code you have there doesn't look like wrong, my first thought would be that the place that you're calling IsInRole() isn't handling a 'false' return correctly.
Is j actually incrementing? or is it somehow being reset it back to 0?
Try this
public bool IsInRole(int roleID)
{
bool inRole = false;
int i = userRoles.GetLength(0);
for (int j = 0; j < i; j++)
{
int k = j;
if (Convert.ToInt32(userRoles[k, 0]) == roleID)
{
inRole = true;
break;
}
}
return inRole;
}
Looking at MSDN's GetLength property, to quote 'An example of GetLength is GetLength(0), which returns the number of elements in the first dimension of the Array.'
public bool IsInRole(int roleID)
{
bool inRole = false;
try{
int i = userRoles.GetLength(0);
for (int j = 0; j < i; j++)
{
if (Convert.ToInt32(userRoles[j, 0]) == roleID)
{
inRole = true;
break;
}
}
}catch(Exception up){
throw up;
}
return inRole;
}
I would be inclined to wrap the logic into a try/catch to see if the Convert.ToInt32 or GetLength(0) is throwing an exception...
Hope this helps,
Best regards,
Tom.
Your loop looks solid so it must be not exiting for a different reason. Could your array contain a value that would cause Convert.ToInt32 to hang or throw?