从包含重复项的数据集中生成一个包含不同列表项的列表
本文关键字:列表 包含不 一个 包含重 数据 数据集 集中 | 更新日期: 2023-09-27 18:26:43
我真的很困,因为你们很多人在这里发布解决方案,总的来说都很出色(IMHO),我想我会看看你们能如何处理这个问题。
一些背景
我正在尝试创建一个列表,该列表必须只包含特定序列中的不同项目。(这是一个主键,因此必须是不同的(我没有把它作为主键,但我必须处理我得到的东西,你知道它是怎么回事)。
为了便于理解这一要求,可以考虑从食谱中创建一个不同的食谱步骤列表。我的问题是,这些"食谱"的"厨师"经常改变他们创作杰作的顺序。
例如:
配方1
- 用叉子搅拌鸡蛋
- 在煎锅里融化人造黄油
- 倒入鸡蛋
- 不停地搅动
- 平板
- 根据需要加入盐和胡椒粉
配方2
- 把鸡蛋打入碗中
- 用叉子搅拌鸡蛋
- 在煎锅中用小火融化人造黄油
- 倒入鸡蛋
- 不停地搅动
- 平板
- 发球
- 根据需要加入盐和胡椒粉
配方3
- 用叉子搅拌鸡蛋
- 根据需要加入盐和胡椒粉
- 在煎锅中用小火融化人造黄油
- 倒入鸡蛋
- 不停地搅动
- 平板
正如你所知,"加盐和胡椒……"在食谱3中不可能是数字2,但在食谱1和2中仍然是正确的顺序。
我想,如果我能识别出"冒犯"的列表项,并在其末尾添加一个句点,从而使其独一无二,这将是一个解决方案。
在C#中,给定一个数据集(通过SQL查询获得),其中重复数据按正确顺序排列,并放入类型字符串的列表中,我该如何做到这一点?LINQ在这里不是一个要求,但如果它提供了一个解决方案,我不怕使用它。
特定代码(或psedo代码):
- 标识需要复制和修改的列表项
- 确定新创建的大列表中的WHERE(假设)是要放置的新修改的列表项
如果你的第一个问题是"给我看看你的作品",请注意,我已经在这方面做了很多工作,而且代码通常很长
我很乐意使用伪代码或使用我的数据集尝试您的代码。我也很乐意阅读其他可能相关的解决方案。
谢谢,我期待看到你的解决方案。
--编辑:我开始有一种印象,如果你不发布代码,人们就不喜欢它。所以它开始了(我在上面说它很长)。代码有效,但不能解决问题。它按顺序返回一个不重复的不同列表。(如果下面的格式不好,请原谅)
public void GetNewRecipeItemsFromDB(string RequestedRecipeName)
{
string connString = string.Empty;
string strGetRecipeElements_Sql = "SQL that returns the dataset";
string connString = GetConnectionString();
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = strGetRecipeElements_Sql;
SqlDataReader reader = null;
try
{
conn.Open();
SqlDataAdapter adapter = new SqlDataAdapter(strGetRecipeElements_Sql, conn);
DataSet RecipeItems = new DataSet();
adapter.Fill(RecipeItems, "RecipeItems");
reader = cmd.ExecuteReader();
List<string> RecipeItemList = new List<string>();
//Create an array with existing RecipeItems
int readerCount = 0;
while (reader.Read())
{
RecipeItems GSI = new RecipeItems();
GSI.RecipeItem = reader[0].ToString();
GSI.Sequence = Convert.ToInt32(reader[1].ToString());
GSI.Rank = Convert.ToInt32(reader[2].ToString());
RecipeItemList.Add(GSI.RecipeItem.ToString());
readerCount++;
}
string[] CurrentRecipeItemArray = new string[readerCount];
string[] UpdatedRecipeItemArray = new string[readerCount];
//RecipeItemList.Sort();
label1.Text = "";
textBox1.Text = "";
CurrentRecipeItemArray = RecipeItemList.ToArray();
for (int y = CurrentRecipeItemArray.Length - 1; y >= 0; y--)
{
textBoxDBOrginal.Text += CurrentRecipeItemArray[y].ToString() + Environment.NewLine;
}
string[] lines = textBoxDBOrginal.Text.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
List<string> UniqueRecipeItemsInvertedList = new List<string>();
if (lines.Length > 0)
{
//OK it's not null lets look at it.
int lineCount = lines.Length;
string NewCompare = string.Empty;
for (int z = 0; z < lineCount; z++)
{
NewCompare = lines[z];
if (!UniqueRecipeItemsInvertedList.Contains(NewCompare))
{
UniqueRecipeItemsInvertedList.Add(NewCompare);
}
}
}
UniqueRecipeItemsInvertedList.Reverse();
foreach (string s in UniqueRecipeItemsInvertedList)
{
if (!string.IsNullOrEmpty(s))
{
listBox7.Items.Add(s.ToString());
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Errors.ToString());
}
conn.Close();
}
}
答案已经在这个网站上了。如何使用LINQ 重命名列表中的重复项
代码为:
IEnumerable<String> GetUnique(IEnumerable<String> list)
{
HashSet<String> itms = new HashSet<String>();
foreach(string itm in list)
{
string itr = itm;
while(itms.Contains(itr))
{
itr = itr + "_";
}
itms.Add(itr);
yield return itr;
}
}
我得出的结论是,尽管这是可以做到的,而且我已经接近了,但我只是没有实现这一目标的技能/知识。
它相当于:
- 循环浏览食谱总数,并将食谱名称放在列表中
- 对于配方列表中的每个配方名称,从数据库中获取配方步骤和序列,并将其放入排序列表中(这是一个不确定的地方)
- 在这一点上,如果您只是想要不同的项目,那么您就拥有了所需的所有数据。ListName.Distinct()
- 循环浏览SortedList以查看键/值是否以正确的顺序存在仍然是我的丧钟。我不断遇到密钥已存在/密钥不存在的异常。如果我能解决这个问题,我就解决了
我学到了很多关于list<>的知识,排序列表<>和List以及拥有自己的类和方法的能力。例如:RecipeInfo.RecipeItemsList让生活变得轻松多了。
我仍然不明白为什么这里没有人愿意碰这个,或者为什么它被降级了。这种经历可能会让我在向stackoverflow.com发布另一个问题之前犹豫不决。
由于Dictionary不允许重复条目(它抛出ArgumentException是未处理的异常),因此处理了确保唯一性和序列顺序的"繁重工作"(仍在测试该项)。我想我使用的是GSI。序列错误,因为收货项目可能有多个序列。(这不是答案,但我可以把代码放在一个地方。我希望我做得对)http://williablog.net/williablog/post/2011/08/30/Generic-AddOrUpdate-Extension-for-IDictionary.aspx
while(reader.Read())
{
RecipeItems GSI = new RecipeItems();
GSI.RecipeItem = reader[0].ToString();
GSI.Sequence = Convert.ToInt32(reader[1].ToString());
GSI.RecipeName = reader[2].ToString();
GSI.MaxSequence = Convert.ToInt32(reader[3].ToString());
if (dictionary.ContainsKey(GSI.RecipeItem))
{
dictionary.[GSI.RecipeItem] = GSI.Sequence);
}
else
{
dictionary.Add(GSI.RecipeItem, GSI.Sequence);
}
}
我认为这里的最终答案是我不一定预见或渴望的。大约有94个独特的项目,在20个食谱的过程中,你最终会得到一个约428个独特食谱项目的列表。这会给我一个列表,在那里我可以按照正确的顺序找到合适的食谱。我仍然认为我在这一点上的逻辑是错误的,但当你认为每个食谱都有几个食谱项目不正常,必须重复,然后乘以食谱的数量时,这是有道理的。