检查int是否为10,100,1000,

时间:2014-06-14 10:01:16

标签: c# numbers

我的应用程序中有一部分需要做某事(=>在其他数字前加上填充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.03HierarchicPosition。这也可能是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;喜欢以下我不是舒尔,我可以解决这个问题:
我正在构建(部分众多)图片库,其中包含CategoriesImages。有一个类别可以有一个父项和多个子项,每个图像属于一个类别(我在我的逻辑中称它们为HolderAsstes - 所以每个图像都有一个持有者,每个类别可以有多个资产) 。这些图像首先按类别位置排序,然后按其自身位置排序。我将HierarchicPositionHolderHierarchicPosition#ItemHierarchicPosition结合起来。因此,在以02.04作为其位置和120张图像的类别中,第3张图像将获得02.04#003 我甚至有一些情况下&#34;三个级别&#34; (或者将来可能更多),如03.1#02#04 我能否适应&#34;双重解决方案&#34;支持这种情况?

P.S。:对于我的基本问题,我也对其他解决方案持开放态度。

2 个答案:

答案 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

因此,每当您移动项目时,您只需要通过查看nn-1

重新计算n+1的位置

根据每个条目的预期孩子数量,您可以从“1000.00”,“10.000”或其他最佳匹配开始。


我没有考虑到:当你想将“2”移到顶部时,你需要重新计算所有“2”的孩子,使其值在“2”的排序值和现在“下一个”项目...可能会让人头疼:)


具有“双”值的解决方案有一些限制,但适用于较小的组。然而,你在谈论“群数,子群和数量为100的图片” - 所以另一种解决方案更可取:

  • 首先,您应该重构数据库:目前您正在尝试将一个树“挤压”到一个列表中(数据表基本上是列表)
  • 要真正反映具有无限深度的树的复杂布局,您应该使用2个表并实现composite pattern
  • 然后你可以使用递归方法来获得一个类别,它的子类别,[...],最后是该类别的元素。
  • 这样,您只需要在其当前节点中提供每个叶子的位置。
  • 重新分类叶子不会影响另一个节点或任何节点的任何叶子。
  • 重新安排节点不会影响该节点的任何子节点或叶子。