读书人

一个泛型运用示例:将一组已经排序的条

发布时间: 2012-12-24 10:43:13 作者: rapoo

一个泛型应用示例:将一组已经排序的条形码按照"相邻编号连续"分组
因实际应用中的需要, 创建了一个泛型类的实例, 欢迎拍砖.


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


// 一个泛型应用示例
// 应用场景: 将一组已经排序的条形码按照"相邻编号连续"分组

public class MyGen<T> where T : IMyBar
{
private List<T> list = null;

public MyGen()
{
list = new List<T>();
}

public void Add(T t)
{
list.Add(t);
}

public void AddRange(List<T> otherList)
{
list.AddRange(otherList);
}

// 计算出分组列表
public List<Range<T>> GetRangeList()
{
List<Range<T>> resultList = new List<Range<T>>();

list.Sort((a, b) => String.Compare(a.Barcode, b.Barcode)); //按照条形码编号排序

for (int i = 0; i < list.Count; i++)
{
if (resultList.Count > 0)
{
Range<T> curRange = resultList.Last();
string nextBarcode = curRange.Start.GetEnd(curRange.Count + 1);
if (list[i].Barcode.Equals(nextBarcode))
{
curRange.Add(list[i]);
}
else
{
resultList.Add(new Range<T>(list[i]));
}
}
else
{
resultList.Add(new Range<T>(list[i]));
}
}

return resultList;
}
}

public class Bar : IMyBar


{
private static readonly int fixedLen = 12;//条码固定长度为12, 编码为 MMCCVVxxxxxx, 后6位为数字,从1开始计数至999999,不足位以0填充

// 判断是否为符合要求的条形码编号
public static bool IsMatch(string barcode)
{
bool result = false;
int index = 0;
if (barcode.Length == fixedLen
&& Int32.TryParse(barcode.Substring(6), out index)
&& index > 0)
{
result = true;
}
return result;
}

// ctor
public Bar()
{
Barcode = String.Empty;
}

public Bar(string barcode)
{
if (IsMatch(barcode))
{
Barcode = barcode;
}
else
{
Barcode = String.Empty;
}
}

// 前缀
public string Prefix
{
get
{
if (IsMatch(Barcode))
{
return Barcode.Substring(0, 6);
}
else
{
return String.Empty;
}
}
}

// 条形码
public string Barcode { get; private set; }

// 获得指定间隔的后续条形码
public string GetEnd(int count)
{
if (count > 0 && IsMatch(Barcode))
{
int index = Convert.ToInt32(Barcode.Substring(6));
if (!(count + index > 1000000))


{
return String.Format("{0}{1:d06}", Prefix, index + count - 1);
}
}
return String.Empty;
}

// 输出
public override string ToString()
{
return Barcode;
}
}

// 泛型类型必须实现的接口: 一个条形码字符串属性 及计算指定间隔的后续条形码的方法
public interface IMyBar
{
string Barcode { get; }
string GetEnd(int count);
}

// 分组信息
public class Range<T> where T : IMyBar
{
public T Start { get; private set; }
public T End { get; private set; }
public int Count { get; private set; }

public Range(T start)
{
Start = start;
End = start;
Count = 1;
}

public int Add(T t)
{
End = t;
return ++Count;
}
}

// 示例
public class Program
{
public static void Main(string[] args)
{
string[] bcs = new string[]
{
"AABBCC000001", "AABBCC000002", "AABBCC000003", "AABBCC000006", "AABBCC000007",
"AABBCC000009", "AABBCD000001", "AABBCD000002", "ADBBCC000001", "DDDDDD"
};
MyGen<Bar> myGen = new MyGen<Bar>();
for (int i = 0; i < bcs.Length; i++)
{
if (Bar.IsMatch(bcs[i]))
{
myGen.Add(new Bar(bcs[i]));
}
}

List<Range<Bar>> list = myGen.GetRangeList();
Console.WriteLine("开始条形码 结束条形码 数量");
foreach (var item in list)
{


Console.WriteLine("{0} {1} {2}", item.Start, item.End, item.Count);
}
}
}

class Product : Bar
{
public Product(string barcode)
: this("unknown", barcode)
{
}

public Product(string name, string barcode)
: base(barcode)
{
Name = name;
CreateTime = DateTime.Now;
}

public string Name { get; set; }
public DateTime CreateTime { get; set; }


public override string ToString()
{
return String.Format("{0},{1},{2}", Name, Barcode, CreateTime);
}

public static List<Range<Product>> GetRangeList(List<Product> list)
{
MyGen<Product> productGen = new MyGen<Product>();
productGen.AddRange(list);

return productGen.GetRangeList();
}

//MyGen<Product> myGen = new MyGen<Product>();
//for (int i = 0; i < bcs.Length; i++)
//{
// if (Bar.IsMatch(bcs[i]))
// {
// myGen.Add(new Product(bcs[i]));
// }
//}

//List<Range<Product>> list = myGen.GetRangeList();
//Console.WriteLine("开始条形码 结束条形码 数量");
//foreach (var item in list)
//{
// Console.WriteLine("{0} {1} {2}", item.Start, item.End, item.Count);
//}
}


[解决办法]
定义个类实现 听简单方便的。
不过还是支持一下,能给大家分享也是挺好的。
[解决办法]
using System;
using System.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
string[] bcs = new string[]
{
"AABBCC000001", "AABBCC000002", "AABBCC000003", "AABBCC000006", "AABBCC000007",


"AABBCC000009", "AABBCD000001", "AABBCD000002", "ADBBCC000001", "DDDDDD"
};
int gid = 0;
Func<string, string, bool> pred = (x, y) =>
{
if (!Regex.IsMatch(x, "\\d+$")
[解决办法]
!Regex.IsMatch(y, "\\d+$")) return false;
if (Regex.Match(x, "^[A-Za-z]+").Value != Regex.Match(y, "^[A-Za-z]+").Value) return false;
return (int.Parse(Regex.Match(x, "\\d+$").Value) - int.Parse(Regex.Match(y, "\\d+$").Value)) == 1;
};
var query = bcs.Take(1).Select(x => new { x, id = gid })
.Concat(bcs.Skip(1).Zip(bcs, (i2, i1) => new { x = i2, id = pred(i2, i1) ? gid : ++gid }))
.GroupBy(x => x.id);
Console.WriteLine("开始条形码 结束条形码 数量");
foreach (var item in query)
{
Console.WriteLine("{0} {1} {2}", item.Min(x => x.x), item.Max(x => x.x), item.Count());
}
}
}
}



就这么几行就行了。
[解决办法]
来学习学习!!!

读书人网 >C#

热点推荐