[英]C# string manipulation to generate a list of strings
我正在嘗試對產品導入進行一些字符串操作,但不幸的是,我有一些重復的數據,如果保留這些數據,則會將產品分配給我不想分配產品的類別。
我有以下字符串:
類別A |類別A>子類別1 |類別B |類別C |類別C |類別2
我想要的結果是:
類別A>子類別1
B類
類別C>子類別2
首先,我對(|)進行分割,得到以下結果:
A類
類別A>子類別1
B類
C類
C類>子類2
然后,我遍歷此列表並濺到(>)上
但我不知道如何合並結果,例如Category A \\ Sub Category 1
下面是代碼。 這將用於處理大約1200行,因此我試圖使其盡可能快。
static void Main(string[] args)
{
string strProductCategories = "Category A|Category A > Sub Category 1|Category B|Category C|Category C > Sub Category 2";
List<string> firstSplitResults = strProductCategories.SplitAndTrim('|');
List<List<string>> secondSplitResults = new List<List<string>>();
foreach( string firstSplitResult in firstSplitResults )
{
List<string> d = firstSplitResult.SplitAndTrim('>');
secondSplitResults.Add(d);
}
// PrintResults(firstSplitResults);
PrintResults2(secondSplitResults);
}
public static void PrintResults(List<string> results)
{
foreach( string value in results)
{
Console.WriteLine(value);
}
}
public static void PrintResults2(List<List<string>> results)
{
foreach(List<string> parent in results)
{
foreach (string value in parent)
{
Console.Write(value);
}
Console.WriteLine(".....");
}
}
}
public static class StringExtensions
{
public static List<string> SplitAndTrim(this string value, char delimter)
{
if( string.IsNullOrWhiteSpace( value))
{
return null;
}
return value.Split(delimter).Select(i => i.Trim()).ToList();
}
}
列表正確后,我將使用(\\)重新加入列表。
任何幫助將非常有用。
UPDATE
數據來自CSV,因此可以有n個級別。
因此,例如:
類別A->此數據是多余的
類別A>子類別1->此數據冗余
類別A>子類別1>子子類別1
類別A>子類別1>子子類別2
將導致:
類別A>子類別1>子子類別1
類別A>子類別1>子子類別2
西蒙
您有一個良好的開始,基本上,您只需要在最后添加一些代碼即可完成解決方案。
foreach( List<string> i in secondSplitResults )
{
if (i.Count == 2)
{
i.RemoveAll(x => x.Count == 1 && x[0] == i[0]);
i.Insert(1,"/");
}
}
PrintResults2(secondSplitResults);
如果刪除標記為“冗余”的葉元素,則可以簡化為在具有共同前綴的項目中找到最長路徑的問題:
class Program
{
static void Main(string[] args)
{
string pathCase1 = "Category A|Category A > Sub Category 1|Category B|Category C|Category C > Sub Category 2";
string pathCase2 = "Category A -> THIS IS DATA IS REDUNDANT|Category A > Sub Category 1 -> THIS IS DATA IS REDUNDANT|Category A > Sub Category 1 > Sub Sub Category 1|Category A > Sub Category 1 > Sub Sub Category 2";
PrintPaths("case1", ParsePaths(pathCase1));
PrintPaths("case2", ParsePaths(pathCase2));
Console.ReadLine();
}
private static void PrintPaths(string name, List<string> paths)
{
Console.WriteLine(name);
Console.WriteLine();
foreach (var item in paths)
{
Console.WriteLine(item);
}
Console.WriteLine();
}
static string NormalizePath(string src)
{
// Remove "-> THIS DATA IS REDUNDANT" elements
int idx = src.LastIndexOf('>');
if (idx > 0 && src[idx - 1] == '-')
{
src = src.Substring(0, idx - 1);
}
var parts = src.SplitAndTrim('>');
return string.Join(">", parts);
}
static List<string> ParsePaths(string text)
{
var items = text.SplitAndTrim('|');
for (int i = 0; i < items.Count; ++i)
{
items[i] = NormalizePath(items[i]);
}
items.Sort();
var longestPaths = new SortedSet<string>();
foreach (var s in items)
{
int idx = s.LastIndexOf('>');
if (idx > 0)
{
var prefix = s.Substring(0, idx);
longestPaths.Remove(prefix);
}
longestPaths.Add(s);
}
return longestPaths.ToList();
}
}
輸出:
case1
Category A>Sub Category 1
Category B
Category C>Sub Category 2
case2
Category A>Sub Category 1>Sub Sub Category 1
Category A>Sub Category 1>Sub Sub Category 2
我可能誤解了這個問題,但是也許我用兩行代碼做到了這一點:
https://dotnetfiddle.net/GyDwar
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
foreach(var part in getParts("Category A|Category A > Sub Category 1|Category B|Category C|Category C > Sub Category 2"))
Console.WriteLine(part);
Console.WriteLine();
Console.WriteLine("TEST 2");
foreach(var part in getParts("Category A > THIS IS DATA IS REDUNDANT|Category A > Sub Category 1 > THIS IS DATA IS REDUNDANT|Category A > Sub Category 1 > Sub Sub Category 1|Category A > Sub Category 1 > Sub Sub Category 2"))
Console.WriteLine(part);
}
public static List<string> getParts(string stringToParse){
var parts = stringToParse.Split('|').Select(part => part.Trim());
return parts.Where(part => !parts.Any(comparePart => part != comparePart && comparePart.StartsWith(part))).ToList();
}
}
結果:
Category A > Sub Category 1
Category B
Category C > Sub Category 2
TEST 2
Category A > THIS IS DATA IS REDUNDANT
Category A > Sub Category 1 > THIS IS DATA IS REDUNDANT
Category A > Sub Category 1 > Sub Sub Category 1
Category A > Sub Category 1 > Sub Sub Category 2
我基本上說的是,將所有部分都作為不組成另一部分開始的部分。
在(|)上分割后,遍歷此列表,並簡單地計算初始字符串中每個列表項字符串的出現次數。 如果項目出現在初始字符串中大於1的位置,則應刪除該項目。 結果列表將是您所需要的。 我在此處使用的初始字符串中每個列表項字符串的計算出現次數如何計算字符串中一個字符串出現的次數? 到目前為止,這是最快的方法
string strProductCategories = "Category A|Category A > Sub Category 1|Category B|Category C|Category C > Sub Category 2";
List<string> firstSplitResults = strProductCategories.SplitAndTrim('|');
for (int i = 0; i < firstSplitResults.Count; i++)
{
int occCount = (strProductCategories.Length - strProductCategories.Replace(firstSplitResults[i], "").Length) / firstSplitResults[i].Length;
if (occCount > 1)
{
firstSplitResults.RemoveAt(i);
i--;
}
}
// print result
for (int i = 0; i < firstSplitResults.Count; i++)
{
Console.WriteLine(firstSplitResults[i]);
}
Console.ReadLine();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.