如何从多值映射中删除“垂直重复”值?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从多值映射中删除“垂直重复”值?相关的知识,希望对你有一定的参考价值。
不幸的是,我正在使用Java中的一些不太美味的数据结构,我的任务是在多值映射(Map<Enum, List<String>>
)中删除我所谓的“垂直重复”,其中所有值(List<String>
)都是相同的大小
这是我的意思的一个例子:
{
// Column : 1 2 3 4 5 6 7 8 9
NUMBER : [ "1", "2", "3", "1", "2", "3", "1", "2", "3" ],
LETTER : [ "A", "B", "C", "A", "E", "F", "G", "B", "I" ],
SYMBOL : [ "!", "!", "!", "!", "!", "!", "!", "!", "!" ],
...
}
“垂直副本”可以是与任何前一列具有相同值的任何列。在上面的地图中,副本将是列[1,4](两者都具有值1,A,!
)和[2,8](两者都具有值2,B,!
)。
删除“垂直重复”后,上面地图的输出:
{
// Previous Column:
// 1 2 3 5 6 7 9
NUMBER : [ "1", "2", "3", "2", "3", "1", "3" ],
LETTER : [ "A", "B", "C", "E", "F", "G", "I" ],
SYMBOL : [ "!", "!", "!", "!", "!", "!", "!" ],
...
}
有没有一种简单的方法来删除“垂直重复”?我正在使用具有不同键集大小的多值映射(一个映射可能有3个不同的枚举键,另一个可能有17个不同的枚举键),以及不同的值集大小(一个映射可能包含每个列表的列表)大小为2,另一个可能包含每个大小为20的列表。
答案
我建议使用基于列的数据结构而不是基于行的数据。至少你可以/应该使用这样的结构进行这个操作,然后你可以添加一个简单的方法,然后将它变回行式多图。这是一个完整功能示例的样子:
public enum Row {
NUMBER, LETTER, SYMBOL, WHATEVER1, WHATEVER2
}
public static class Col {
Map<Row, String> col = new HashMap<>();
public Col(Entry<Row, String>... entries) {
for (Entry<Row, String> entry: entries) {
col.put(entry.getKey(), entry.getValue());
}
}
// to use within a LinkedHashSet
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
return Objects.equals(col, ((Col) other).col);
}
@Override
public int hashCode() { return Objects.hash(col); }
@Override
public String toString() { return col.toString(); }
}
public static void main(String[] argv) {
// alternatively use LinkedHashSet directly
List<Col> cols = new ArrayList<>();
cols.add(new Col(new SimpleEntry<>(Row.NUMBER, "1"), new SimpleEntry<>(Row.LETTER, "A"), new SimpleEntry<>(Row.WHATEVER1, "X")));
cols.add(new Col(new SimpleEntry<>(Row.NUMBER, "2"), new SimpleEntry<>(Row.LETTER, "B"), new SimpleEntry<>(Row.SYMBOL, "!")));
cols.add(new Col(new SimpleEntry<>(Row.NUMBER, "1"), new SimpleEntry<>(Row.LETTER, "A"), new SimpleEntry<>(Row.WHATEVER1, "X")));
// turn original structure unique keeping order of insertion
Set<Col> unique = new LinkedHashSet<>(cols);
System.out.println(unique);
}
打印
[{LETTER = A,NUMBER = 1,WHATEVER1 = X},{LETTER = B,NUMBER = 2,SYMBOL =!}]
另一答案
根据时间或空间限制,有不同的方法,但您可以为每个列值(例如Map<String, Integer>
)构建直方图,并删除计数为2或更多的所有列。这应该比将每列与每个其他列进行比较更有效。
以上是关于如何从多值映射中删除“垂直重复”值?的主要内容,如果未能解决你的问题,请参考以下文章