我有一个n项(对象)的列表,这些项已根据列出的顺序加权,具有较高权重的列表中的第一项。有些项目是重复的,所以我试图在列表中留下该项目的单个实例,并根据权重的平均值将其分配到列表中的位置,例如:(ItemA_weight1 + ItemA_weight 2+ ... / Amount列表中的项目)
例如,有以下列表:
skillsViewModel = new List<SkillViewModel>()
{
new SkillViewModel()
{
Name = "a",
Weight = 6
},
new SkillViewModel()
{
Name = "b",
Weight = 5
},
new SkillViewModel()
{
Name = "c",
Weight = 4
},
new SkillViewModel()
{
Name = "a",
Weight = 3
},
new SkillViewModel()
{
Name = "c",
Weight = 2
},
new SkillViewModel()
{
Name = "e",
Weight = 1
}
};
项目“a”和“c”是重复的,所以我需要得到一个新的列表,其中所有项目都是不同的,只有来自dupes的项目存在一个,所以它将产生下面的列表。 BTW列表中的每个项目都有一个新的权重,基于他的位置和新列表的项目总数:
新名单:
skillsViewModel = new List<SkillViewModel>()
{
new SkillViewModel()
{
Name = "b",
Weight = 4
},
new SkillViewModel()
{
Name = "c",
Weight = 3
},
new SkillViewModel()
{
Name = "a",
Weight = 2
},
new SkillViewModel()
{
Name = "e",
Weight = 1
}
};
“a”和“c”的新位置计算如下:初始权重的总和并在列表中的项目数量之间进行划分。
e.g:
var averageWeight = 0;
foreach (var d in dupes)
{
averageWeight = averageWeight + d.Weight;
}
"a" position = averageWeight = (int)Math.Ceiling((Decimal)averageWeight /
(Decimal)skillsViewModel.Count());
a=1.5
=>所以它四舍五入到2
对于项目“c”= 1 =>相同,因此位置1,我需要根据其先前的位置填充列表中的其余项目的左侧位置。
我遇到的问题是,如果我将操作四舍五入以计算其中一个欺骗的位置,则由于其权重,它可以是其他重复项目可以获得的相同位置。
有什么好的通用算法来实现这种行为,我使用的是C#?
你当前的方法有一个缺点,即属性Weight
依赖于上下文,但是对象本身从不“知道”它的上下文,所以属性必须从外部设置。而你提到的第二个缺点是:两个物体不能有相同的位置。
您可以在权重数组中对对象进行排序:
int[] weights;
weights[1][] = new SkillViewModel(){ ... }
weights[1][] = new SkillViewModel(){ ... }
weights[2][] = new SkillViewModel(){ ... }
weights[2][] = new SkillViewModel(){ ... }
你仍然可以通过添加位置作为键来使数组更复杂但更详细(借口,我的代码可能在语法错误,我不是在C#
中编程):
int[] weights;
int weights[1][] = position;
weights[1][1] = new SkillViewModel(){ ... }
weights[1][2] = new SkillViewModel(){ ... }
int weights[2][] = position;
weights[2][4] = new SkillViewModel(){ ... }
weights[2][3] = new SkillViewModel(){ ... }
像这样的数组,像Position
或Weight
这样的上下文在每个SkillViewModel
本身内部都是完全未知的,它可能只包含属性name
:
new SkillViewModel(){
Name = 'e';
}
当然可以在List-object而不是数组中创建一个类似的结构,但我认为你得到的结论是在SkillViewModel
s之外确定了上下文,而不再需要它作为内部属性。
另一种方法具有我在第一句中写的相同的缺点,但允许进一步的细节:你可以添加属性position
:
new SkillViewModel()
{
Name = "e",
Position = 1,
Weight = 1
}
像这样Position
和Weight
从代码中的物理位置解开,也可以获得与另一个对象相同的值。
编辑:
也许你会忘记这个想法,即元素的分类是如此重要和决定。为每个对象分配所需/所需的值,并按重量或位置对它们进行排序,您可以使用不同的方法对view
进行排序和创建。