1

The struct below consists of three variables, bool visible, int id, and int order.

List<Data.myStruct> itemList = new List<Data.myStruct>();

Then I add four items to the list

itemList.Add(new Data.myStruct(false, 1, 0));
itemList.Add(new Data.myStruct(false, 2, 0));
itemList.Add(new Data.myStruct(false, 3, 0));
itemList.Add(new Data.myStruct(false, 4, 0));

I can make a function to set the visibility of a given id to true.

public void setVisible(int id) {
    for(int i = 0; i < itemList.Count; i++)
    {
        if(id == itemList[i].id)
        {
            itemList[i] = new Data.myStruct(true, itemList[i].id, itemList[i].order);
        }
    }
}

My question would be this, How would I be able to set the order of each item in the itemList when bool visible = true based on when setVisible(int id) is called. So if setVisible(1) is called before setVisible(2) then the order of the second one would be greater than the first one, or vice versa.

For Example,

setVisible(1);
setVisible(2);

Result:

itemList[0].visible = true, itemList[0].id = 1, itemList[0].order = 1
itemList[1].visible = true, itemList[1].id = 2, itemList[1].order = 2
itemList[2].visible = false, itemList[2].id = 3, itemList[2].order = 0
itemList[3].visible = false, itemList[3].id = 4, itemList[3].order = 0

And if I were to change the visibility to false on one of them, How might I change the order to fill in the gap. Can this be done using linq?

Edit:

How would I be able to loop through the list by order of highest order value?

27
  • I'm having a hard time understanding your question.. Are you trying to sort the list? Commented Mar 5, 2015 at 23:26
  • @Default Yes I am, but basing it off the order variable, and whether or not the visible variable is true. Commented Mar 5, 2015 at 23:27
  • Looping through the list can be done via OrderBy and ThenBy. But I'm not sure how to apply it to your question. Commented Mar 5, 2015 at 23:27
  • 1
    May I suggest to use class instead of struct so that you don't have to recreate the item? Then you would be able to change the properties directly. Or are you locked to struct? Commented Mar 5, 2015 at 23:34
  • 1
    But in your example the result is different from what you just described. Commented Mar 6, 2015 at 0:19

2 Answers 2

1

Are you just looking for a function to calculate the next order when setting visible to true.

Something along the lines of:

 public void setVisible(int id, List<Data.myStruct> itemList)
 {
     Func<List<Data.myStruct>, int> getNextOrder = list =>
     {
         if (itemList.Any(item => item.order > 0))
             return itemList.Max(item => item.order) - 1;

         return itemList.Count - 1;
     }; 

     for (int i = 0; i < itemList.Count; i++)
     {
         if (id == itemList[i].id && !itemList[i].visible)
         {
             itemList[i] = new Data.myStruct(true, itemList[i].id, getNextOrder(itemList));
         }
     }
 }

You also mentioned if you could use LINQ to update orders. LINQ should only ever be used for querying, so you should never use it to mutate the state of objects.

The above code obviously only accounts for setting visibility to true. If you need to set the visibilty of an item to false you should use a foreach loop to update the other orders afterwards.

EDIT:

Based on the revision to your question, the below code will set the visible item to the highest order and then re-order the other items:

public static void setVisible(int id, List<Data.myStruct> itemList)
{
    int previousOrder = int.MinValue;

    for (int i = 0; i < itemList.Count; i++)
    {
        if (id == itemList[i].id)
        {
            previousOrder = itemList[i].order;
            itemList[i] = new Data.myStruct(true, itemList[i].id, itemList.Count - 1);
        }
    }

    if (previousOrder == int.MinValue)
        return;

    for (int i = 0; i < itemList.Count; i++)
    {
        if (itemList[i].id != id && itemList[i].order > 0 && itemList[i].order >= previousOrder)
        {
            var order = itemList[i].order - 1;
            itemList[i] = new Data.myStruct(true, itemList[i].id, order);
        }
    }
}

To output values to console:

foreach (var item in itemList.OrderByDescending(i => i.order))
{
    Console.WriteLine(string.Format("{0} - {1} - {2}", item.id, item.visible, item.order));
}
Sign up to request clarification or add additional context in comments.

6 Comments

If I were to type setVisible(1) twice in a row, then instead of it outputting the order with 3, it would move it down to 2, if I call a setVisible() twice i'd like it to stay at the highest order. Sorry for not being clear with that.
Added another version of function to answer revised question
--itemList[i].order will return with an error, since were using structs you cannot modify the value because it's not a variable. Instead would itemList[i].order - 1 be a solution?
If i were to put the into a console application, how could I be able to write them in order? I tried using the OrderByDescending() and ThenByDescending() but i'm having problems.
If you just want to order by descending use itemList.OrderByDescending(i => i.Order); (See edit to answer)
|
0

Beside your list, you can store another variable, say int currentOrder=0; And every time you do a setVisible call, set the order of that particular item to

++currentOrder

Can't post fancy code because I'm on the Android app.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.