【字符串排序】C#和前端js排序问题

前言#

前端请求时做了个参数验证,就是简单的计算md5,但是与后端计算的结果始终不一致

发现是前后端对字符串排序的默认规则有区别

测试代码#

前端#

1、示例代码,可以在浏览器的控制台中直接运行

e=["","","1","a","d","B","你好","你0","你d","你A",",","你."]
e.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0));
console.log(e);

2、运行结果

['', ',', '1', 'B', 'a', 'd', '你', '你.', '你0', '你A', '你d', '你好']


后端#

1、示例代码

var arr = new string[] { "", "", "1", "a", "d", "B", "你好", "你0", "你d", "你A", ",", "你." };
var r = "'" + string.Join("', '", arr.OrderBy(x => x)) + "'";
Console.WriteLine(r);

2、运行结果

'', ',', '1', '你', '你.', '你0', '你好', '你A', '你d', 'a', 'B', 'd'

 

分析规则#

前端:

空 -> 标点符号 -> 数字 -> 大写字母 -> 小写字母 -> 汉字

后端:

空 -> 标点符号 -> 数字 -> 汉字 -> 字母(不区分大小写)

解决方案#

方案1-自定义字符串对比规则#

复制代码
private static void SortByCompare(string[] arr)
{
    var r = string.Join(" ", arr.OrderBy(x => x, new StringComparer()));
    Console.WriteLine(r);
}
public class StringComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        int orderX = 0;
        int orderY = 0;

        if (!string.IsNullOrWhiteSpace(x))
            orderX = GetOrder(x[0]);
        if (!string.IsNullOrWhiteSpace(y))
            orderY = GetOrder(y[0]);

        if (orderX == orderY)
            return string.Compare(x, y, StringComparison.Ordinal);
        return orderX.CompareTo(orderY);
    }

    private int GetOrder(char c)
    {
        if (char.IsPunctuation(c))
            return 10;
        if (char.IsDigit(c))
            return 20;
        else if (char.IsUpper(c))
            return 30;
        else if (char.IsLower(c))
            return 40;
        return 999;
    }
}
复制代码

方案2-使用V8引擎调用js方法#

1、项目添加以下Nuget引用

Microsoft.ClearScript.Core

Microsoft.ClearScript.V8

Microsoft.ClearScript.V8.Native.win-x64

2、项目添加js文件,示例:calc.js,内容如下

复制代码
function sortParameter(data) {
    if (!data) {
        return "";
    }
    var e = JSON.parse(data);

    e.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0));
    return e.join(" ");
}
复制代码

 

 3、编写方法

private static V8ScriptEngine _engine = new();
private static void SortByV8(string[] arr)
{
    _engine.Execute(File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "calc.js"), Encoding.UTF8));
    string json = arr.ToJson();
    object r = _engine.Invoke("sortParameter", [json]);
    Console.WriteLine(r);
}

验证#

1、后端代码

var arr = new string[] { "", "123", "all", "delay", "Basic", ",./" };

SortByCompare(arr);
SortByV8(arr);

 

2、后端运行结果

 ,./ 123 Basic all delay
 ,./ 123 Basic all delay

3、前端代码

e=["", "123", "all", "delay", "Basic", ",./"]
e.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0));
console.log(e);

 

4、前端运行结果

['', ',./', '123', 'Basic', 'all', 'delay']

总结#

按照这个场景,这2个方案都能实现,但也各有优劣。

方案1-自定义规则,

(1)是C#语言的实现,

(2)但只处理了首个字符的逻辑处理

(3)且未处理汉字的逻辑

方案2-V8引擎调用js

(1)比较重,单独引用了类库

(2)无须重新实现逻辑了,直接执行js的逻辑

 

posted @   我有我奥妙  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示
CONTENTS