C# 逻辑练习

85 阅读5分钟

一、需求

例:现有一数据表存储筛选规则,如下表

年龄性别负责人
大于20张三
小于20李四
大于20王五

根据筛选条件,选择负责人,若后期新增或修改筛选规则,要求不能和之前重复

如添加下面条件,则符合规则

年龄性别负责人
小于20赵六

若添加下面条件,则不符合规则,因为与第一条数据的筛选条件冲突

年龄性别负责人
大于20赵六

二、逻辑说明

2.1 创建实体类

假设有4个筛选条件,分别抽象为F1,F2,F3,F4

image.png

2.2 筛选规则说明

并且可取的值只能为三种:

  1. 数字(表示该条件对应的id)
  2. ALL (不进行筛选)
  3. ELSE (若所有筛选条件没有命中,则选择该条件)

初始化数据:

image.png

假设数据库存放三条筛选规则:

第一条:

F1F2F3F4ID
1,2,3,42,3,4ALLALL1

一共有 4 * 3 = 12种条件,此时若符合则让ID为1的用户处理,该12种分别是:

image.png

image.png

image.png

第二条:

F1F2F3F4ID
ALL2,3,4ALLALL2

一共有 3 种条件,此时若符合则让ID为2的用户处理,分别是:

image.png

第二条:

F1F2F3F4ID
ELSEELSEELSEELSE3

若上述条件都没有命中,则让ID为3的用户处理

image.png

2.3 新增筛选条件

2.3.1 在 新增的数据与数据库中内容重复 的条件下

如新增一条筛选规则,让id为4的用户处理

image.png

此时数据重复,将会报错并返回重复信息,以下是重复信息

image.png

2.3.2 在 新增的数据与数据库中内容不重复 的条件下

如新增一条不重复的筛选规则,让id为4的用户处理

image.png

此时由于没有重复信息,将不会返回重复列表

image.png

2.4 修改筛选条件

分别定义before和after,分别代表要修改的数据,和要修改后的数据

要求修改后的规则,不能与现有规则冲突

image.png

2.4.1 在 修改后的数据与已有内容重复 的条件下

例如修改后的条件与第一行内容重复,要求返回重复的条件列表

image.png

image.png

2.4.2 在 修改后的数据与已有内容不重复 的条件下

当修改后后的条件不与现有的冲突时,则可正常修改

image.png

三、代码实现

3.1 实体类

 public class Filter

    {

        public int Id { get; set; }

        public string F1 { get; set; }

        public string F2 { get; set; }

        public string F3 { get; set; }

        public string F4 { get; set; }

    }

3.2 返回结果类

 public class ResultHandler

    {

        public bool flag { get; set; }

        public List<Filter> filters { get; set; }



        public ResultHandler()

        {

            flag = false;

            filters = new List<Filter>();

        }

    }

3.2 处理过程

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace select
{
    internal static class Helper
    {

        public static ResultHandler IsExist(Filter before, Filter after,List<Filter> list)
        {
            // 分别拆解
            List<string> b1 = GetListByString(before.F1);
            List<string> b2 = GetListByString(before.F2);
            List<string> b3 = GetListByString(before.F3);
            List<string> b4 = GetListByString(before.F4);

            List<string> a1 = GetListByString(after.F1);
            List<string> a2 = GetListByString(after.F2);
            List<string> a3 = GetListByString(after.F3);
            List<string> a4 = GetListByString(after.F4);

            ResultHandler resultHandler = new ResultHandler();
            bool isBefore = false;
            int index = 1;
            list.ForEach(x =>
            {
                b1.ForEach(a =>
                {
                    b2.ForEach(b =>
                    {
                        b3.ForEach(c =>
                        {
                            b4.ForEach(d =>
                            {
                                if (x.F1.Equals(a) && x.F2.Equals(b) && x.F3.Equals(c) && x.F4.Equals(d))
                                {
                                    Console.WriteLine($"遇到自己,跳过:f1:{a},f2:{b},f3:{c},f4:{d}");
                                    isBefore = true;
                                    return; // 直接返回到 f4.ForEach 的下一个元素
                                }
                            });
                            if (isBefore) return; // 跳出 f3.ForEach
                        });
                        if (isBefore) return; // 跳出 f2.ForEach
                    });
                    if (isBefore) return; // 跳出 f1.ForEach
                });
                // Console.WriteLine($"现在是第{index ++ }次循环");
                if (isBefore) return; // 跳出 list.ForEach
                else
                {
                    // Console.WriteLine("不是自己,处理");
                    bool found = false;

                        a1.ForEach(a =>
                        {
                            a2.ForEach(b =>
                            {
                                a3.ForEach(c =>
                                {
                                    a4.ForEach(d =>
                                    {
                                        if (x.F1.Equals(a) && x.F2.Equals(b) && x.F3.Equals(c) && x.F4.Equals(d))
                                        {
                                            resultHandler.flag = true;
                                            resultHandler.filters.Add(new Filter
                                            {
                                                F1 = a,
                                                F2 = b,
                                                F3 = c,
                                                F4 = d
                                            });
                                            found = true;
                                            return; // 直接返回到 f4.ForEach 的下一个元素
                                        }
                                    });
                                    if (found) return; // 跳出 f3.ForEach
                                });
                                if (found) return; // 跳出 f2.ForEach
                            });
                            if (found) return; // 跳出 f1.ForEach
                        });
                }
            });
            return resultHandler;
        }

        public static ResultHandler IsExist(Filter target,List<Filter> list)
        {
            // 拆解target
            List<string> f1 = GetListByString(target.F1);
            List<string> f2 = GetListByString(target.F2);
            List<string> f3 = GetListByString(target.F3);
            List<string> f4 = GetListByString(target.F4);

            ResultHandler resultHandler = new ResultHandler();


            bool found = false;
            list.ForEach(x =>
            {
                f1.ForEach(a =>
                {
                    f2.ForEach(b =>
                    {
                        f3.ForEach(c =>
                        {
                            f4.ForEach(d =>
                            {
                                if (x.F1.Equals(a) && x.F2.Equals(b) && x.F3.Equals(c) && x.F4.Equals(d))
                                {
                                    resultHandler.flag = true;
                                    resultHandler.filters.Add(new Filter
                                    {
                                        F1 = a,
                                        F2 = b,
                                        F3 = c,
                                        F4 = d
                                    });
                                    found = true;
                                    return; // 直接返回到 f4.ForEach 的下一个元素
                                }
                            });
                            if (found) return; // 跳出 f3.ForEach
                        });
                        if (found) return; // 跳出 f2.ForEach
                    });
                    if (found) return; // 跳出 f1.ForEach
                });
                if (found) return; // 跳出 list.ForEach
            });
            return resultHandler;
        }

        public static List<Filter> GetFilter(int id,List<string>l1, List<string> l2, List<string> l3, List<string> l4)
        {
            List<Filter> filters = new List<Filter>();
            l1.ForEach(a =>
            {
                l2.ForEach(b =>
                {
                    l3.ForEach(c =>
                    {
                        l4.ForEach(d =>
                        {
                            filters.Add(new Filter {
                                Id = id,
                                F1 = a,
                                F2 = b,
                                F3 = c,
                                F4 = d
                            });
                        });
                    });
                });
            });

            return filters;
        }

        public static List<string> GetListByString(string str)
        {
            if("ALL".Equals(str) || "ELSE".Equals(str))
            {
                return new List<string> { str };
            }
            else
            {
                List<string> list = new List<string>();
                string[] strings = str.Split(',');
                for(int i = 0; i < strings.Length; i++)
                {
                    list.Add(strings[i]);
                }
                return list;
            }
        }

        public static List<Filter> Get()
        {
            Filter f1 = new Filter
            {
                F1 = "1,2,3,4" ,
                F2 = "2,3,4" ,
                F3 = "ALL" ,
                F4 = "ALL" 
            };
            Filter f2 = new Filter
            {
                F1 = "ALL",
                F2 = "2,3,4",
                F3 = "ALL",
                F4 = "ALL"
            };
            Filter f3 = new Filter
            {
                F1 = "ELSE",
                F2 = "ELSE",
                F3 = "ELSE",
                F4 = "ELSE"
            };
            return new List<Filter>()
            {
                f1,f2,f3
            };
        }

    }
}

3.3 逻辑测试

// See https://aka.ms/new-console-template for more information
using select;

List<Filter> data = Helper.Get();

// 生成条件集合
List<Filter> result = new List<Filter>();
int index = 1;
data.ForEach(x =>
{
    string f1 = x.F1;
    string f2 = x.F2;
    string f3 = x.F3;
    string f4 = x.F4;
    List<string> f1List = Helper.GetListByString(f1);
    List<string> f2List = Helper.GetListByString(f2);
    List<string> f3List = Helper.GetListByString(f3);
    List<string> f4List = Helper.GetListByString(f4);

    result.AddRange(Helper.GetFilter(index++, f1List, f2List, f3List, f4List));
});

Console.WriteLine(result);

// add
// 1. 测试重复: 1 2 ALL ALL
Filter filter1 = new Filter
{
    Id = 4,
    F1 = "1,2,3",
    F2 = "2",
    F3 = "ALL",
    F4 = "ALL",
};
var res  = Helper.IsExist(filter1,result);
Console.WriteLine(res);
// 2.测试不重复
Filter filter2 = new Filter
{
    Id = 4,
    F1 = "6,7,8",
    F2 = "2",
    F3 = "ALL",
    F4 = "ALL",
};
var res2 = Helper.IsExist(filter2, result);
Console.WriteLine(res2);


// update: before => after
Filter before = new Filter
{
    Id = 2,
    F1 = "ALL",
    F2 = "2,3,4",
    F3 = "ALL",
    F4 = "ALL",
};

// 修改后重复
Filter after = new Filter
{
    Id = 2,
    F1 = "1,2,3",
    F2 = "2",
    F3 = "ALL",
    F4 = "ALL",
};
var res3 = Helper.IsExist(before, after, result);
Console.WriteLine(res3);


// 修改后不重复
Filter after1 = new Filter
{
    Id = 2,
    F1 = "6,7,8",
    F2 = "2",
    F3 = "ALL",
    F4 = "ALL",
};
var res4 = Helper.IsExist(before, after1, result);
Console.WriteLine(res4);

四、项目地址

select: 模拟权限管理系统 (gitee.com)