惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
博客园 - 【当耐特】
小众软件
小众软件
A
About on SuperTechFans
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
Vercel News
Vercel News
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threatpost
人人都是产品经理
人人都是产品经理
H
Help Net Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LINUX DO - 热门话题
B
Blog
F
Full Disclosure
P
Proofpoint News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Threat Research - Cisco Blogs
L
LangChain Blog
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Project Zero
Project Zero
I
InfoQ
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Cloudflare Blog
V
Vulnerabilities – Threatpost
云风的 BLOG
云风的 BLOG
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Check Point Blog
K
Kaspersky official blog
WordPress大学
WordPress大学
腾讯CDC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
Securelist
T
Tenable Blog
N
News and Events Feed by Topic
The GitHub Blog
The GitHub Blog
W
WeLiveSecurity
Stack Overflow Blog
Stack Overflow Blog
O
OpenAI News
Blog — PlanetScale
Blog — PlanetScale
量子位
Simon Willison's Weblog
Simon Willison's Weblog
T
Tor Project blog
P
Proofpoint News Feed

博客园 - 我有我奥妙

【BenchmarkDotNet】测试多方式的对象映射 【自动注入】.NET8/.NETCore 依赖注入:自动注入项目中所有接口和自定义类 【排名】处理同分数的排名 【Quartz】.Net8使用定时任务 【模型验证】未被异常捕获到 【Ant Design Vue】相关 【根节点】C#找树形数据的根节点Id 【C#】枚举值 【ECharts】图表自定义显示标题 【消息队列】介绍 【Nginx】Windows部署Vue 设计模式(一)-介绍 【.NetCore】创建本机的静态文件服务器 NLog(一)-使用示例 【nssm】windows上netcore注册为服务 【长路经】C#读取文件抛出FileNotFoundException异常 【RestSharp】常用的几个请求方式 【笔记软件】Obsidian的使用 【浏览器扩展】编写Firefox和Chrome的扩展程序
【字符串排序】C#和前端js排序问题
我有我奥妙 · 2025-01-08 · via 博客园 - 我有我奥妙

前言

前端请求时做了个参数验证,就是简单的计算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的逻辑