Linq/Lambda OrderBy Delegate for List of IP Addresses

前端 未结 6 631
粉色の甜心
粉色の甜心 2021-01-01 21:34

Given List ips = new List();

I need to sort the list of IP addresses in a logical order (i.e. \"192.168.0.2\" comes before \

6条回答
  •  囚心锁ツ
    2021-01-01 22:30

    I wrote an IpComparer for IPv6. The variant from Howel doesn't work.

    Here is the Comparer:

    /// 
    /// Compares two ip addresses.
    /// http://stackoverflow.com/questions/4785218/linq-lambda-orderby-delegate-for-liststring-of-ip-addresses
    /// 
    public class IpComparer : IComparer
    {
        /// 
        /// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
        /// 
        /// 
        /// 
        /// A signed integer that indicates the relative values of  and , as shown in the following table.
        /// Value Meaning Less than zero is less than .
        /// Zero equals .
        /// Greater than zero  is greater than .
        /// 
        /// The first object to compare.The second object to compare.
        public int Compare(IPAddress x, IPAddress y)
        {
            if (ReferenceEquals(x, null))
            {
                throw new ArgumentNullException("x");
            }
    
            if (ReferenceEquals(y, null))
            {
                throw new ArgumentNullException("y");
            }
    
            byte[] bytesOfX = x.GetAddressBytes();
            byte[] bytesOfY = y.GetAddressBytes();
    
            return StructuralComparisons.StructuralComparer.Compare(bytesOfX, bytesOfY);
        }
    }
    

    And here a unit test:

    [TestFixture]
    public class IpComparerTest : AbstractUnitTest
    {
        private IpComparer _testee;
    
        [SetUp]
        public void Setup()
        {
            _testee = new IpComparer();
        }
    
        [TestCase("10.156.35.205", "10.156.35.205")]
        [TestCase("0.0.0.1", "0.0.0.1")]
        [TestCase("2001:0db8:0000:08d3:0000:8a2e:0070:7344", "2001:db8:0:8d3:0:8a2e:70:7344")]
        [TestCase("2001:0db8:0:0:0:0:1428:57ab", "2001:db8::1428:57ab")]
        [TestCase("2001:0db8:0:0:8d3:0:0:0", "2001:db8:0:0:8d3::")]
        [TestCase("::ffff:127.0.0.1", "::ffff:7f00:1")]
        public void Compare_WhenIpsAreEqual_ThenResultIsZero(string ip1, string ip2)
        {
            // Arrange
            IPAddress x = IPAddress.Parse(ip1);
            IPAddress y = IPAddress.Parse(ip2);
    
            // Act and Assert
            Assert.That(_testee.Compare(x, y), Is.EqualTo(0));
        }
    
        [TestCase("10.156.35.2", "10.156.35.205")]
        [TestCase("0.0.0.0", "0.0.0.1")]
        [TestCase("1001:0db8:85a3:08d3:1319:8a2e:0370:7344", "2001:0db8:85a3:08d3:1319:8a2e:0370:7344")]
        [TestCase("2001:0db8:85a3:08d3:1319:8a2e:0370:7343", "2001:0db8:85a3:08d3:1319:8a2e:0370:7344")]
        public void Compare_WhenIp1IsLessThanIp2_ThenResultIsLessThanZero(string ip1, string ip2)
        {
            // Arrange
            IPAddress x = IPAddress.Parse(ip1);
            IPAddress y = IPAddress.Parse(ip2);
    
            // Act and Assert
            Assert.That(_testee.Compare(x, y), Is.LessThan(0));
        }
    
        [TestCase("10.156.35.205", "10.156.35.2")]
        [TestCase("0.0.0.1", "0.0.0.0")]
        [TestCase("3001:0db8:85a3:08d3:1319:8a2e:0370:7344", "2001:0db8:85a3:08d3:1319:8a2e:0370:7344")]
        [TestCase("2001:0db8:85a3:08d3:1319:8a2e:0370:7345", "2001:0db8:85a3:08d3:1319:8a2e:0370:7344")]
        public void Compare_WhenIp1IsGreaterThanIp2_ThenResultIsGreaterThanZero(string ip1, string ip2)
        {
            // Arrange
            IPAddress x = IPAddress.Parse(ip1);
            IPAddress y = IPAddress.Parse(ip2);
    
            // Act and Assert
            Assert.That(_testee.Compare(x, y), Is.GreaterThan(0));
        }
    }
    

    I hope this solution is correct. I'm not an expert in IPv6.

提交回复
热议问题