Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by giraffe1 · Dec 31, 2015 at 03:36 PM · listcollectionsgeneric list

Questions regarding IComparer

What is the difference between:

 public class SortDistance : IComparer<EnemyInfo>
     {
         public int Compare(EnemyInfo a, EnemyInfo b)
         {
             //Sort descending
             if (a.distance < b.distance) {return 1;}
             else if (a.distance > b.distance) {return -1;}
             else {return 0;}
         }
     }

And:

 public class SortDistance : IComparer<EnemyInfo>
     {
         public int Compare(EnemyInfo a, EnemyInfo b)
         {
             //Sort ascending
             return Comparer<float>.Default.Compare(a.distance, b.distance);
         }
     }

Other than sorting in opposite directions they seem to do the same thing? What is the difference?

Another question, I also have an "inSight" bool in the EnemyInfo constructor. Instead of sorting all the elements by distance. Can I sort only the elements where inSight = true? Would the if statement be placed in the SortDistance class? or in the method where I invoke Sort?

Any help appreciated, Thanks a lot.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Elier · Dec 31, 2015 at 03:53 PM 0
Share

They are the same, but on the first one the 1 and -1 are reversed. Usually 1 indicates that the first argument (or the object itself) is "greater" than the other object.

What do you want to do with the enemies that are not in sight? they have to be put somewhere when you sort the collection (unless you remove them before sorting).

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Dec 31, 2015 at 04:06 PM

I've never seen someone using

 return Comparer<float>.Default.Compare(a.distance, b.distance);

In most cases the comparison boils down to some kind of primitive type. Those usually have a CompareTo method. So you could simply do

 return a.distance.CompareTo(b.distance);

if you want to sort them in reverse order, just swap a and b.

There's no real difference between your first and second implementation besides that you reversed the sorting order.

About your second question: That doesn't make much sense. When you sort a List or generally a collection of objects you don't remove or add elements. They are simply sorted. A comparer just tells the sorting algorithm if, when comparing two elements, one element should come before or after the other or if it doesn't matter.

In most cases it doesn't make sense to create a seperate IComparer class. If you just want to be able to sort the elements, your EnemyInfo class could implement the IComparable interface. That way you can define a default sorting for your class. If you need a specific sorting order, you can simply use lambda expressions:

 list.Sort( (a,b)=>a.distance.CompareTo(b.distance) );

If you want to remove certain elements from a collection you can use linq. For example:

 using System,Linq;
 
 //...
 var inSightSorted = list.Where(a=>a.inSight).Sort( (a,b)=>a.distance.CompareTo(b.distance) ).ToList();

In this case we create a new list out of the old one, we remove all elements where inSight is false and sort the resulting enumeration by distance all in just one line ^^.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image giraffe1 · Dec 31, 2015 at 09:34 PM 0
Share

Thanks

The reason I do not want to remove inSight false elements is so I can keep track of last known positions of AI's that left our sight. Then I can set possible secondary targets or thirdary targets in the future.

And the reason I choose IComparer is so I can sort by multiple different variables. Can you set more than 1 type using IComparable in the constructor?

avatar image Bunny83 giraffe1 · Jan 01, 2016 at 05:42 PM 0
Share

You don't need a IComparer to sort on multiple variables. An IComparer object or a Comparison delegate will do the exact same thing. So if i got you right you want to pretend that objects which have inSight == false to be at a far distance so they are sorted to the end of the list? In that case you can simply use a method like this:

 public static int SortByDistCheckInSight(EnemyInfo a, EnemyInfo b)
 {
     if (a.inSight ^ b.inSight) // either a or b is not insight
     {
         if (!a.inSight)
             return 1;
         return -1;
     }
     return a.distance.CompareTo(b.distance);
 }
 
 list.Sort(SortByDistCheckInSight);

With the xor check we test if one and only one of the two objects is not in sight. If both are in sight or if both are not insight we simply sort by distance. However if one of them is not in sight but the other is we always say that the object that is not insight has a higher value than the one insight.

I'm not sure if i placed the "1" and "-1" correctly, they might need to be swapped.

If the overall sorting should be reversed you can add this method:

 public static int SortByDistCheckInSightReversed(EnemyInfo a, EnemyInfo b)
 {
     return SortByDistCheckInSight(b, a);
 }
avatar image giraffe1 Bunny83 · Jan 03, 2016 at 01:45 AM 0
Share

Yes, that was what I was trying to achieve. I will check it out your solution. This stuff is tricky to wrap my head around! First time using lists let alone delegates and comparisons!

Thanks,

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

34 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

how is it possible that my List has count = 3, but after im trying to compare onClick obhects name it says that my list is empty 0 Answers

[SOLVED] Converting a Generic List to JSON in Unity 3 Answers

Building tycoon game, need help storing variables into an array. 1 Answer

Coin Counter showing total coins per level help 0 Answers

Why is my for loop not instantiating object at correct possision from List 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges