添加注释添加项目文件。
This commit is contained in:
210
VoiceToFunctionDemo/Program.cs
Normal file
210
VoiceToFunctionDemo/Program.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace VoiceToFunction
|
||||
{
|
||||
|
||||
class Program
|
||||
{
|
||||
// 初始化函数库(明确参数类型要求)
|
||||
private static List<FunctionInfo> functionLibrary = new List<FunctionInfo>
|
||||
{
|
||||
// 1. 乘积函数(参数:两个double数组)
|
||||
new FunctionInfo
|
||||
{
|
||||
Name = "PRODUCT",
|
||||
Description = "计算多列对应行的乘积",
|
||||
Synonyms = new List<string> { "计算乘积", "相乘", "乘积" },
|
||||
MinParams = 2,
|
||||
ParamTypes = new List<Type> { typeof(double[]), typeof(double[]) },
|
||||
Execute = (args) =>
|
||||
{
|
||||
double[] col1 = (double[])args[0];
|
||||
double[] col2 = (double[])args[1];
|
||||
return col1.Zip(col2, (a, b) => a * b).ToArray();
|
||||
}
|
||||
},
|
||||
|
||||
// 2. 筛选函数(参数:用户列表 + 筛选条件)
|
||||
new FunctionInfo
|
||||
{
|
||||
Name = "FILTER",
|
||||
Description = "筛选满足条件的数据",
|
||||
Synonyms = new List<string> { "筛选", "过滤", "选出" },
|
||||
MinParams = 2,
|
||||
ParamTypes = new List<Type> { typeof(List<User>), typeof(Func<User, bool>) },
|
||||
Execute = (args) =>
|
||||
{
|
||||
List<User> users = (List<User>)args[0];
|
||||
Func<User, bool> condition = (Func<User, bool>)args[1];
|
||||
return users.Where(condition).ToList();
|
||||
}
|
||||
},
|
||||
|
||||
// 3. 统计函数(参数:销售额数组 + 统计条件)
|
||||
new FunctionInfo
|
||||
{
|
||||
Name = "COUNTIF",
|
||||
Description = "统计满足条件的记录数",
|
||||
Synonyms = new List<string> { "统计数量", "计数", "数一下" },
|
||||
MinParams = 2,
|
||||
ParamTypes = new List<Type> { typeof(double[]), typeof(Func<double, bool>) },
|
||||
Execute = (args) =>
|
||||
{
|
||||
double[] sales = (double[])args[0];
|
||||
Func<double, bool> condition = (Func<double, bool>)args[1];
|
||||
return sales.Count(condition);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// 测试带复杂参数的语音指令
|
||||
TestVoiceCommand("计算C列和D列的乘积,C列是[1,3,5],D列是[2,4,6]");
|
||||
TestVoiceCommand("计算A列和B列的乘积,A列是[1,3,5],B列是[2,4,6]");
|
||||
TestVoiceCommand("筛选出年龄大于28且姓名包含'李'的用户");
|
||||
TestVoiceCommand("统计销售额在5000到20000之间的订单数,数据是[3000, 8000, 15000, 25000]");
|
||||
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
static void TestVoiceCommand(string voiceText)
|
||||
{
|
||||
Console.WriteLine($"=== 语音指令:{voiceText} ===");
|
||||
ParsedResult result = ParseVoiceCommand(voiceText);
|
||||
|
||||
if (!string.IsNullOrEmpty(result.Error))
|
||||
{
|
||||
Console.WriteLine($"错误:{result.Error}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验参数类型是否匹配函数要求
|
||||
var function = functionLibrary.First(f => f.Name == result.FunctionName);
|
||||
bool paramTypeMatch = function.ParamTypes.Zip(result.ParamTypes,
|
||||
(required, actual) => required.Name == actual).All(match => match);
|
||||
if (!paramTypeMatch)
|
||||
{
|
||||
Console.WriteLine("错误:参数类型与函数要求不匹配");
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行函数并输出结果
|
||||
var executionResult = function.Execute(result.Parameters);
|
||||
Console.WriteLine($"匹配函数:{result.FunctionName}");
|
||||
Console.WriteLine($"执行结果:{GetResultString(executionResult)}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
// 核心:解析语音文本,提取函数+参数(强化入参处理)
|
||||
static ParsedResult ParseVoiceCommand(string text)
|
||||
{
|
||||
var result = new ParsedResult();
|
||||
|
||||
// 1. 匹配函数(同之前逻辑)
|
||||
FunctionInfo matchedFunction = functionLibrary.FirstOrDefault(
|
||||
func => func.Synonyms.Any(syn => text.Contains(syn)));
|
||||
if (matchedFunction == null)
|
||||
{
|
||||
result.Error = "未找到匹配的函数";
|
||||
return result;
|
||||
}
|
||||
result.FunctionName = matchedFunction.Name;
|
||||
|
||||
// 2. 提取并解析参数(根据函数类型动态处理)
|
||||
try
|
||||
{
|
||||
switch (matchedFunction.Name)
|
||||
{
|
||||
case "PRODUCT":
|
||||
// 提取列数据(支持显式输入如"[1,3,5]")
|
||||
var colDataMatches = Regex.Matches(text, @"\[([\d, ]+)\]")
|
||||
.Cast<Match>()
|
||||
.Select(m => m.Groups[1].Value.Split(',').Select(double.Parse).ToArray())
|
||||
.ToList();
|
||||
if (colDataMatches.Count < 2)
|
||||
{
|
||||
result.Error = "PRODUCT需要至少两列数据,格式如'[1,2,3]'";
|
||||
return result;
|
||||
}
|
||||
result.Parameters = new object[] { colDataMatches[0], colDataMatches[1] };
|
||||
result.ParamTypes = new[] { "Double[]", "Double[]" };
|
||||
break;
|
||||
|
||||
case "FILTER":
|
||||
// 提取年龄条件(如"大于28")和姓名条件(如"包含'李'")
|
||||
int ageThreshold = 0;
|
||||
string nameKeyword = null;
|
||||
|
||||
var ageMatch = Regex.Match(text, @"年龄(大于|小于|等于)(\d+)");
|
||||
if (ageMatch.Success)
|
||||
{
|
||||
string op = ageMatch.Groups[1].Value;
|
||||
ageThreshold = int.Parse(ageMatch.Groups[2].Value);
|
||||
}
|
||||
|
||||
var nameMatch = Regex.Match(text, @"姓名包含'([^']+)'");
|
||||
if (nameMatch.Success)
|
||||
{
|
||||
nameKeyword = nameMatch.Groups[1].Value;
|
||||
}
|
||||
|
||||
// 组合多条件筛选器
|
||||
Func<User, bool> condition = u =>
|
||||
(ageMatch.Success ? (ageMatch.Groups[1].Value == "大于" ? u.Age > ageThreshold : u.Age < ageThreshold) : true) &&
|
||||
(nameMatch.Success ? u.Name.Contains(nameKeyword) : true);
|
||||
|
||||
// 模拟用户数据(实际应从数据源获取)
|
||||
var users = new List<User>
|
||||
{
|
||||
new User { Name = "张三", Age = 25 },
|
||||
new User { Name = "李四", Age = 30 },
|
||||
new User { Name = "李白", Age = 29 },
|
||||
new User { Name = "王五", Age = 35 }
|
||||
};
|
||||
|
||||
result.Parameters = new object[] { users, condition };
|
||||
result.ParamTypes = new[] { "List<User>", "Func<User, Boolean>" };
|
||||
break;
|
||||
|
||||
case "COUNTIF":
|
||||
// 提取数值范围(如"5000到20000")和数据
|
||||
var rangeMatch = Regex.Match(text, @"(\d+)到(\d+)");
|
||||
if (!rangeMatch.Success)
|
||||
{
|
||||
result.Error = "COUNTIF需要范围条件,如'5000到20000'";
|
||||
return result;
|
||||
}
|
||||
double min = double.Parse(rangeMatch.Groups[1].Value);
|
||||
double max = double.Parse(rangeMatch.Groups[2].Value);
|
||||
|
||||
// 提取销售额数据
|
||||
var salesData = Regex.Match(text, @"\[([\d, ]+)\]")
|
||||
.Groups[1].Value.Split(',').Select(double.Parse).ToArray();
|
||||
|
||||
result.Parameters = new object[] { salesData, (Func<double, bool>)(s => s >= min && s <= max) };
|
||||
result.ParamTypes = new[] { "Double[]", "Func<Double, Boolean>" };
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Error = $"参数解析失败:{ex.Message}";
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static string GetResultString(object result)
|
||||
{
|
||||
if (result is double[] nums) return string.Join(", ", nums);
|
||||
if (result is List<User> users) return string.Join(", ", users.Select(u => $"{u.Name}({u.Age})"));
|
||||
if (result is int count) return count.ToString();
|
||||
return "未知结果";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user