Q1. 如下代码中两个datatable (dt1,dt2), 关联关系code,ver两列,如果存在就用dt2.name更新dt1.name,不存在将数据插入dt1中,就像SQL SERVER 中的merge,要求不能循环
禁止使用循环的要求非常扯淡,会导致漫无目的地对着空气优化,无论是认为自带的比较/排序效率一定比手写更高,还是觉得自带的比较/排序效率一定比手写更低都不可取。实现代码(挑出dt1独有的行,并把dt2的数据追加进去,无需更新操作,合并结果一定是新数据):
DataTable dt1 = new DataTable();
dt1.Columns.Add(new DataColumn("code", typeof(string)));
dt1.Columns.Add(new DataColumn("ver", typeof(string)));
dt1.Columns.Add(new DataColumn("name", typeof(string)));
DataTable dt2 = dt1.Clone();
dt1.Rows.Add('1', '1', "张三");
dt1.Rows.Add('2', '1', "a1");
dt1.Rows.Add('3', '1', "a2");
dt2.Rows.Add('1', '1', "张三1");
dt2.Rows.Add('2', '1', "222");
dt2.Rows.Add('3', '1', "333");
dt2.Rows.Add('5', '1', "333");
dt2.Rows.Add('6', '1', "333");
var rows1 = dt1.AsEnumerable();
var rows2 = dt2.AsEnumerable();
var keys2 = rows2.Select(r => $"{r["code"]}#{r["ver"]}");
dt1 = rows1.Where(r => !keys2.Contains($"{r["code"]}#{r["ver"]}")).Concat(rows2).CopyToDataTable();
foreach (DataRow row in dt1.Rows)
{
Console.WriteLine(string.Join(",", row.ItemArray));
}
1,1,张三1
2,1,222
3,1,333
5,1,333
6,1,333
Q2. 目标路径下有很多同文件名,不同后缀名的文件,比如1.ZIP和1,RAR这种,我要把所有同文件名,后缀名是RAR的文件删掉。
实现代码:
var keys = System.IO.Directory.GetFiles(@"C:\xxx").GroupBy(f => Regex.Match(f, ".+(?=\\.[^.]+$)").Value);
//按文件名称(不带后缀)作为key,对所有文件进行分组
foreach (var g in keys)
{
//如果某个名称有多种后缀的文件结果,就删除rar结尾的文件;
//如果某个名称只有一个文件,就不处理
if (g.Count() >= 2)
{
try
{
System.IO.File.Delete($"{g.Key}.rar");
}//尝试删除.rar文件,也别管有没有这个文件了。
catch (Exception) { }
}
}
Q3. 将键值对按照QueryString规则拼接,键名需要按字典排序,并取md5(32位大写格式)
实现代码:
var paras = new Dictionary<string, string> { { "key", key }, { "secret", secret }, { "userMobile", userMobile }, { "refereeMobile", refereeMobile } };
var result = string.Join("&", paras.Select(kv => $"{kv.Key}={kv.Value}").OrderBy(v => v));
result = BitConverter.ToString(((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(Encoding.UTF8.GetBytes(result))).Replace("-", "").ToUpper();
Q4.窗口有一个TextBox可以输入多行,输入一个数,按回车到下一行,如果不输入的话按回车不会到下一行,继续留在本行
实现代码:
#在TextChanged事件里,删除所有空行
private void txtInput_TextChanged(object sender, EventArgs e)
{
var pos = txtInput.SelectionStart;
txtInput.Text = Regex.Replace(txtInput.Text, "^\r\n", "",RegexOptions.Multiline);
txtInput.SelectionStart = pos;
}
#或者用^$匹配空行的首尾
txtInput.Text = Regex.Replace(txtInput.Text, @"^(\s+)$", "", RegexOptions.Multiline);
Q5. 假如有个List<t>结构如何下:
月份 数量
10月 104
10月 101
11月 106
11月 107
11月 102
11月 103
12月 108
12月 100
12月 105
请问如何找到不同月份的最大值装入字典中?
结果:
key 10月 value 104
key 11月 value 107
key 12月 value 108
实现代码(用GroupBy()方法对数据分组,然后每个分组分别取最大值):
class Program
{
static void Main(string[] args)
{
List<data> list = new List<data> {
new data("10月",104),
new data("10月",101),
new data("11月",106),
new data("11月",107),
new data("11月",102),
new data("11月",103),
new data("12月",108),
new data("12月",100),
new data("12月",105)
};
Dictionary<string, int> result =
new Dictionary<string, int>(
list.GroupBy(d => d.month).Select(g => new KeyValuePair<string, int>(g.Key, g.Max(d => d.value))));
foreach (var kv in result)
{
Console.WriteLine(kv.Key + "\t" + kv.Value);
}
Console.ReadKey();
}
}
class data
{
public string month { get; set; }
public int value { get; set; }
public data(string m, int v)
{
month = m;
value = v;
}
}
Q6. 限制用户名只能输入数字、字母、下划线
实现代码:
//必须包含指定字符,但也允许其它字符:
Regex.IsMatch(input, "[a-zA-Z0-9_]+") == true
// #@aA08 -> true
//空字符串 -> false
//只能包含,且可为空(做法有正查和反查两种):
Regex.IsMatch(input, "[^a-zA-Z0-9_]") == false //不包含其它字符,可为空
//空字符串 -> true
//或者
Regex.IsMatch(input, "^[a-zA-Z0-9_]*$") == true //全文只包含指定字符,可为空
//空字符串 -> true
//只包含,且不可为空(可空不可空的区别在于 * 和 +):
Regex.IsMatch(input, "^[a-zA-Z0-9_]+$") == true //全文只包含指定字符,且至少1位
//空字符串 -> false