简体   繁体   English

从索引组合计算索引

[英]Calculating an index from a combination of indexes

I have a 2D list that might look something like this: 我有一个二维列表,可能看起来像这样:

List<List<object>> myCategories;

Now each inner list is a list of options in a category. 现在,每个内部列表都是类别中选项的列表。 It's a jagged collection, so there might be 2 options in the first list and 4 in the second. 这是一个锯齿状的集合,因此第一个列表中可能有2选项,第二个列表中有4 2选项。

Now I'm transforming that into rows for each combination of categories so, in my example, I'd expect to end up with 2 * 4 = 8 rows in total. 现在,我将其转换为每种类别组合的行,因此,在我的示例中,我期望最终总共有2 * 4 = 8行。 Which would be arranged like so: 安排如下:

Row | Cat 0    | Cat 1
 0  | Item 0_0 | Item 1_0
 1  | Item 0_0 | Item 1_1
 2  | Item 0_0 | Item 1_2
 3  | Item 0_0 | Item 1_3
 4  | Item 0_1 | Item 1_0
 5  | Item 0_1 | Item 1_1
 6  | Item 0_1 | Item 1_2
 7  | Item 0_1 | Item 1_3

Now what I'm struggling with is, given an array of indexes into each category, say [1,2] , the row I need would be 6 because that's where I have item 1 from category 0 and item 2 from category 1 . 现在,我正在苦苦挣扎的是,给定每个类别的索引数组,例如[1,2] ,我需要的行将是6因为那是我拥有类别0项目1和类别1项目2地方。

I had something like this (where idx is a List<int> with my indexes): 我有这样的事情(其中idx是带有索引的List<int> ):

var rowIdx = idx.Select((v, i) => new { v, i }).Aggregate(0, (c, n) =>
{
    c += n.v * Math.Max(1, myCategories.Skip(n.i + 1).Sum(a => a.Count));
    return c;
});

Which works great with 1 or 2 categories, but falls apart once you hit three categories. 它适用于1个或2个类别,但是一旦您击中三个类别,它就会崩溃。 For example, if you have 4 , 1 and 1 as the Count of each category, and you are looking for the row corresponding to item 1 in category 0 (and obviously 0 and 0 in the other two, because there is only one choice), you end up with an index of 2 instead of 1 . 举例来说,如果你有411作为Count每个类别的,和你正在寻找相应的行项目1类别0 (显然00在其他两个,因为只有一个选择) ,您最终得到2而不是1的索引。

Here's a fiddle : 这是一个小提琴

var categories = new List<List<object>>()
{
    new List<object>(){ null, null },
    new List<object>(){ null, null, null, null }
};

var idx = new List<int>() { 1, 2 };

var rowIdx = CalcIndex(categories,idx);

Console.WriteLine(rowIdx);      // outputs 6 as expected

categories = new List<List<object>>()
{
    new List<object>() { null, null, null, null },
    new List<object>() { null },
    new List<object>() { null }
};

idx = new List<int>() { 2, 0, 0 };

rowIdx = CalcIndex(categories,idx);

Console.WriteLine(rowIdx);      // should give 2, but gives 4 instead.

public static int CalcIndex(List<List<object>> categories, List<int> idx) 
{
    return idx.Select((v, i) => new { v, i }).Aggregate(0, (c, n) =>
    {
        c += n.v * Math.Max(1, categories.Skip(n.i + 1).Sum(a => a.Count));
        return c;
    });
}

As long as you know the lower (usually 0) and upper (usually n-1) bounds of each index range, you can call the correct "row" for an almost infinite amount of inidices: 只要您知道每个索引范围的下限(通常为0)和上限(通常为n-1),就可以为几乎无限量的指令调用正确的“行”:

sample: 4D list with sizes 2, 4, 6, 8. 样本:尺寸为2、4、6、8的4D列表。
GetRow (1,2,3,4) -> 1×4×6×8 + 2×6×8 + 3×8 + 4 (row numbering starting at 0) GetRow(1,2,3,4)-> 1×4×6×8 + 2×6×8 + 3×8 + 4(行编号从0开始)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM