我的应用程序中有一部分需要做某事(=>在其他数字前加上填充0)当指定的数字得到一个额外的数字时,意味着它得到10,100,1000左右。 ..
目前我使用以下逻辑:
public static bool IsNewDigit(this int number)
{
var numberString = number.ToString();
return numberString.StartsWith("1")
&& numberString.Substring(1).All(c => c == '0');
}
我能做到:
if (number.IsNewDigit()) { /* add padding 0 to other numbers */ }
这似乎是一个" hack"给我使用字符串转换。
是否有更好的东西(甚至可能是#34;内置")来做这件事?
更新
我需要这个的一个例子:
我有一个具有以下(简化)结构的项目:
public class Item
{
public int Id { get; set; }
public int ParentId { get; set; }
public int Position { get; set; }
public string HierarchicPosition { get; set; }
}
HierarchicPosition
是自己的位置(使用填充)和父级HierarchicPositon
。例如。一个项目,即位置2的项目中的第3个子项,其2.03
为HierarchicPosition
。这也可能是011.7.003.2.02
更复杂的事情
然后,该值用于在&#34树视图中非常容易地对项目进行排序。喜欢结构。
现在我有IQueryable<Item>
并希望添加一个项目作为另一个项目的最后一个孩子。为了避免需要重新创建所有HierarchicalPosition
我想检测(使用相关逻辑)新位置是否添加新数字:
Item newItem = GetNewItem();
IQueryable<Item> items = db.Items;
var maxPosition = items.Where(i => i.ParentId == newItem.ParentId)
.Max(i => i.Position);
newItem.Position = maxPosition + 1;
if (newItem.Position.IsNewDigit())
UpdateAllPositions(items.Where(i => i.ParentId == newItem.ParentId));
else
newItem.HierarchicPosition = GetHierarchicPosition(newItem);
更新#2:
我从DB查询这个位置字符串,如:
var items = db.Items.Where(...)
.OrderBy(i => i.HierarchicPosition)
.Skip(pageSize * pageNumber).Take(pageSize);
因此,我不能使用IComperator
(或其他类似的东西&#34;通过代码&#34;)。
这将返回HierarchicPosition
之类的项目(pageSize = 10
):
03.04
03.05
04
04.01
01年4月1日
02年4月1日
04.02
01年2月4日
04.03
05
更新#3:
我喜欢具有double
值的替代解决方案,但我有一些&#34;更复杂的情况&#34;喜欢以下我不是舒尔,我可以解决这个问题:
我正在构建(部分众多)图片库,其中包含Categories
和Images
。有一个类别可以有一个父项和多个子项,每个图像属于一个类别(我在我的逻辑中称它们为Holder
和Asstes
- 所以每个图像都有一个持有者,每个类别可以有多个资产) 。这些图像首先按类别位置排序,然后按其自身位置排序。我将HierarchicPosition
与HolderHierarchicPosition#ItemHierarchicPosition
结合起来。因此,在以02.04
作为其位置和120张图像的类别中,第3张图像将获得02.04#003
我甚至有一些情况下&#34;三个级别&#34; (或者将来可能更多),如03.1#02#04
我能否适应&#34;双重解决方案&#34;支持这种情况?
P.S。:对于我的基本问题,我也对其他解决方案持开放态度。
答案 0 :(得分:1)
您可以检查数字的基数为10的对数是否为整数。 (10 - > 1,100 - > 2,1000 - > 3,......)
这也可以简化您的算法。您不必在每次找到更大的内容时添加一个填充0,只需跟踪您看到的最大数量,然后选择length = floor(log10(number))+1
并确保所有内容都填充到length
。这部分不会遇到像整数那样的浮点运算问题。
答案 1 :(得分:1)
根据您的描述,您的HierarchicPosition
位置应该维护项目的顺序,并且遇到问题,当您拥有ID 1..9
并添加10
时,你会在某个地方得到订单1,10,2,3,4,5,6...
,因此想要向左翻到01,02,03...,10
- 是否正确?
如果我是对的,请先看一下:https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem
因为您尝试做的是以某种方式解决问题的工作方式。 - 但实际上真正解决它可能会有更有效的方法。 (因此,您应该更好地询问您的实际问题,而不是您尝试实施的解决方案)
在此处查看解决方案,使用自定义IComparator以本机方式对字符串(实际上是数字)进行排序:http://www.codeproject.com/Articles/11016/Numeric-String-Sort-in-C
有关您的更新的更新:
通过像你一样提供排序“String”,你可以在某个地方插入一个元素而不必重新索引所有后续项目,因为它将是一个整数值。 (这似乎是目的)
您可以使用Double-Value快速实现完全相同的结果,而不是构建复杂的“String”:
如果您在2个现有项目之间插入一个项目,您只需要:this.sortingValue = (prior.sortingValue + next.sortingValue) / 2
并在插入列表末尾时处理该案例。
我们假设您按以下顺序添加元素:
1 First Element // pick a double value for sorting - 100.00 for example. -> 100.00
2 Next Element // this is the list end - lets just add another 100.00 -> 200.00
1.1 Child // this should go "in between": (100+200)/2 = 150.00
1.2 Another // between 1.1 and 2 : (150+200)/2 = 175
当您现在根据该双字段进行简单排序时,顺序为:
100.00 -> 1
150.00 -> 1.1
175.00 -> 1.2
200.00 -> 2
想加1.1.1
?太棒了:positon = (150.00 + 175.00)/2;
;
只要您的新值达到x.5
*,就可以简单地将全部乘以10,以确保您没有超出小数位数(但您不必 - 让.5 .25 .125 ...
不会影响排序):
因此,在添加1.1.1
162,5
后,将所有乘以10:
1000.00 -> 1
1500.00 -> 1.1
1625.00 -> 1.1.1
1750.00 -> 1.2
2000.00 -> 2
因此,每当您移动项目时,您只需要通过查看n
和n-1
n+1
的位置
根据每个条目的预期孩子数量,您可以从“1000.00”,“10.000”或其他最佳匹配开始。
我没有考虑到:当你想将“2”移到顶部时,你需要重新计算所有“2”的孩子,使其值在“2”的排序值和现在“下一个”项目...可能会让人头疼:)
具有“双”值的解决方案有一些限制,但适用于较小的组。然而,你在谈论“群数,子群和数量为100的图片” - 所以另一种解决方案更可取:
composite pattern
。