Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IOrderComparer唯一订购情况_C#_Linq - Fatal编程技术网

C# IOrderComparer唯一订购情况

C# IOrderComparer唯一订购情况,c#,linq,C#,Linq,我正在尝试以一种独特的方式订购混合字符串,我想知道是否有其他人这样做过。我已经找到了几篇关于使用IOrderConparer的文章,但没有找到解决我的特殊排序问题的方法 我有以下资料: 1017、650、650C、650B、W323、10、20、1000、W1000 我需要按如下顺序订购: 10、20、650、650B、650C、1000、1017、W323、W1000 任何帮助都将不胜感激。谢谢。使用strmplogicalw执行比较: [DllImport("shlwapi.dll", Ch

我正在尝试以一种独特的方式订购混合字符串,我想知道是否有其他人这样做过。我已经找到了几篇关于使用IOrderConparer的文章,但没有找到解决我的特殊排序问题的方法

我有以下资料:

1017、650、650C、650B、W323、10、20、1000、W1000

我需要按如下顺序订购:

10、20、650、650B、650C、1000、1017、W323、W1000


任何帮助都将不胜感激。谢谢。

使用strmplogicalw执行比较:

[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string x, string y);

这将进行逻辑(考虑数字)字符串比较,而不是基于标准字符串的比较,这将为您提供所需的结果。

稍长一点,但所有托管代码

public class LogicalSorter : IComparer
{
    public int Compare(object a, object b)
    {
        var first = Regex.Split((string)a,"([0-9]+)").Where(s => s != "").ToArray();
        var second = Regex.Split((string)b,"([0-9]+)").Where(s => s != "").ToArray();

        var endIdx = Math.Min(first.Count(), second.Count());

        for (var i = 0; i < endIdx; i++)
        {
            var part1 = first.ElementAt(i);
            var part2 = second.ElementAt(i);

            if (part1.All(char.IsDigit) && part2.All(char.IsDigit) && part1 != part2)
            {
                return int.Parse(part1).CompareTo(int.Parse(part2));
            }

            if (part1 != part2) return part1.CompareTo(part2);
        }

        return first.Count().CompareTo(second.Count());
    }
}
或使用Mrinal建议的仿制药(首选)

公共类逻辑排序器:IComparer
{
公共整数比较(字符串a、字符串b)
{
var first=Regex.Split(a,“([0-9]+)”),其中(s=>s!=”).ToArray();
var second=Regex.Split(b,“([0-9]+)”),其中(s=>s!=”).ToArray();
var endIdx=Math.Min(first.Count(),second.Count());
对于(变量i=0;i
优化的托管代码示例(用于速度而非外观),在regex版本中执行

public class LogicalSorter : IComparer<String>
{
    public int Compare(String a, String b)
    {
        var aLength = a.Length;
        var bLength = b.Length;
        var aIdx = 0;
        var bIdx = 0;
        int aPartLen;
        int bPartLen;
        int aPartEndIndex;
        int bPartEndIndex;
        bool aIsString;
        bool bIsString;

        // Examine both strings on character level, keep track of where
        // we are in each string since lengths might differ
        while (aIdx < aLength && bIdx < bLength)
        {
            // If both strings contain digit at current index
            // compare numbers
            if (char.IsDigit(a[aIdx]) && char.IsDigit(b[bIdx]))
            {
                // Get longest consecutive list of digits from each string
                aPartEndIndex = aIdx;
                while (aPartEndIndex < aLength && char.IsDigit(a[aPartEndIndex])) { aPartEndIndex++; }

                bPartEndIndex = bIdx;
                while (bPartEndIndex < bLength && char.IsDigit(b[bPartEndIndex])) { bPartEndIndex++; }

                aPartLen = aPartEndIndex - aIdx;
                bPartLen = bPartEndIndex - bIdx;

                // Compare lengths (longest number is greater)
                if (aPartLen != bPartLen) return aPartLen < bPartLen ? -1 : 1;

                // Same length numbers, compare chars until not same or end
                while (aIdx < aPartEndIndex && a[aIdx] == b[bIdx])
                {
                    aIdx++;
                    bIdx++;
                }

                // If not at end compare last characters that were not same
                if(aIdx != aPartEndIndex)
                    return a[aIdx] < b[bIdx] ? -1 : 1;
            }
            else
            {
                // Comparing string vs number or string vs string
                aIsString = char.IsLetter(a[aIdx]);
                bIsString = char.IsLetter(b[bIdx]);

                // if not 2 strings, number is always first
                if (aIsString != bIsString) return aIsString ? 1 : -1;

                // Get longest consecutive list of letters from each string
                aPartEndIndex = aIdx;
                while (aPartEndIndex < aLength && (char.IsLetter(a[aPartEndIndex]) == aIsString))
                {
                    aPartEndIndex++;
                }

                bPartEndIndex = bIdx;
                while (bPartEndIndex < bLength && (char.IsLetter(b[bPartEndIndex]) == bIsString))
                {
                    bPartEndIndex++;
                }

                // Compare chars until not same or end
                while (aIdx < aPartEndIndex && bIdx < bPartEndIndex && a[aIdx] == b[bIdx])
                {
                    aIdx++;
                    bIdx++;
                }

                // if not at end compare last letters found
                if ((aIdx != aPartEndIndex) || (bIdx != bPartEndIndex))
                    return a[aIdx] < b[bIdx] ? -1 : 1;
            }
        }

        // Use length as tie breaker
        return aLength < bLength ? -1 : 1;
    }
}
公共类逻辑排序器:IComparer
{
公共整数比较(字符串a、字符串b)
{
var aLength=a.长度;
var bLength=b.长度;
var-aIdx=0;
var-bIdx=0;
国际公寓;
int bPartLen;
国际公寓指数;
int bPartEndIndex;
布尔爱斯林;
布尔比斯林;
//在字符级别检查两个字符串,跟踪其中的位置
//因为长度可能不同,所以我们在每个字符串中
而(aIdx
订购背后的逻辑是什么?是的,只是你没有阅读问题。他在询问分拣顺序。他需要的是逻辑排序,而不是字符串排序。在.Net范例中,自定义IComparer是更好的选择,而不是使用非托管代码的PInvoke。还可以让我们了解PInvoke是您正在投影的其他人的代码,首先创建自己的版本,然后再开始性能测试bandwagon@Cyberdrew这是一个纯托管代码的解决方案,它会很快让你大吃一惊!工作起来很有魅力!为什么PInvoke用于逻辑字符串比较,应该有一种管理方式来实现itLOL。。。嗯,pinvoke版本比您的托管版本快10倍以上,所以我想我会使用pinvoke版本,因为我关心性能:)。在您的梦中,pinvoke将击败托管代码,您可能希望检索您的语句,否则很明显您对.Net framework及其工作方式一无所知。不要去宣称它,因为你所看到的并不是最有效的IComparer代码。同样,当你发表这样的声明时,是否愿意在我的梦中发布一些数据来支持你的版本?你真的读过他写的代码吗?李瑞杰
public class LogicalSorter : IComparer<String>
{
    public int Compare(String a, String b)
    {
        var first = Regex.Split(a, "([0-9]+)").Where(s => s != "").ToArray();
        var second = Regex.Split(b, "([0-9]+)").Where(s => s != "").ToArray();

        var endIdx = Math.Min(first.Count(), second.Count());

        for (var i = 0; i < endIdx; i++)
        {
            var part1 = first.ElementAt(i);
            var part2 = second.ElementAt(i);

            if (part1.All(char.IsDigit) && part2.All(char.IsDigit) && part1 != part2)
            {
                return int.Parse(part1).CompareTo(int.Parse(part2));
            }

            if (part1 != part2) return part1.CompareTo(part2);
        }

        return first.Count().CompareTo(second.Count());
    }
}
public class LogicalSorter : IComparer<String>
{
    public int Compare(String a, String b)
    {
        var aLength = a.Length;
        var bLength = b.Length;
        var aIdx = 0;
        var bIdx = 0;
        int aPartLen;
        int bPartLen;
        int aPartEndIndex;
        int bPartEndIndex;
        bool aIsString;
        bool bIsString;

        // Examine both strings on character level, keep track of where
        // we are in each string since lengths might differ
        while (aIdx < aLength && bIdx < bLength)
        {
            // If both strings contain digit at current index
            // compare numbers
            if (char.IsDigit(a[aIdx]) && char.IsDigit(b[bIdx]))
            {
                // Get longest consecutive list of digits from each string
                aPartEndIndex = aIdx;
                while (aPartEndIndex < aLength && char.IsDigit(a[aPartEndIndex])) { aPartEndIndex++; }

                bPartEndIndex = bIdx;
                while (bPartEndIndex < bLength && char.IsDigit(b[bPartEndIndex])) { bPartEndIndex++; }

                aPartLen = aPartEndIndex - aIdx;
                bPartLen = bPartEndIndex - bIdx;

                // Compare lengths (longest number is greater)
                if (aPartLen != bPartLen) return aPartLen < bPartLen ? -1 : 1;

                // Same length numbers, compare chars until not same or end
                while (aIdx < aPartEndIndex && a[aIdx] == b[bIdx])
                {
                    aIdx++;
                    bIdx++;
                }

                // If not at end compare last characters that were not same
                if(aIdx != aPartEndIndex)
                    return a[aIdx] < b[bIdx] ? -1 : 1;
            }
            else
            {
                // Comparing string vs number or string vs string
                aIsString = char.IsLetter(a[aIdx]);
                bIsString = char.IsLetter(b[bIdx]);

                // if not 2 strings, number is always first
                if (aIsString != bIsString) return aIsString ? 1 : -1;

                // Get longest consecutive list of letters from each string
                aPartEndIndex = aIdx;
                while (aPartEndIndex < aLength && (char.IsLetter(a[aPartEndIndex]) == aIsString))
                {
                    aPartEndIndex++;
                }

                bPartEndIndex = bIdx;
                while (bPartEndIndex < bLength && (char.IsLetter(b[bPartEndIndex]) == bIsString))
                {
                    bPartEndIndex++;
                }

                // Compare chars until not same or end
                while (aIdx < aPartEndIndex && bIdx < bPartEndIndex && a[aIdx] == b[bIdx])
                {
                    aIdx++;
                    bIdx++;
                }

                // if not at end compare last letters found
                if ((aIdx != aPartEndIndex) || (bIdx != bPartEndIndex))
                    return a[aIdx] < b[bIdx] ? -1 : 1;
            }
        }

        // Use length as tie breaker
        return aLength < bLength ? -1 : 1;
    }
}