将具有相同前缀入口键的映射值分组。

huangapple go评论79阅读模式
英文:

Group Values of map with same prefix entry key

问题

我有一个哈希映射其中包含类似a.01a.02b.01b.02的字符串并且值是列表

现在我想创建一个新的映射并将原映射中的键的前缀如ab等作为新映射的键将具有相似前缀的元素的列表内容作为值

示例将具有前缀a和b的列表分组
输入Map<String, List> input = {(a.1, l1), (a.2, l2), (b.1, l3), (b.2, l4)}
输出Map<String, List> output = {(a, {l1, l2}), (b, {l3, l4})}

我尝试了以下方法但它不起作用

public static Set<String> prefixName(final Map<String, List> names, final String prefix) {
    return names.entrySet().stream()
        .filter(entry -> entry.getKey().startsWith(prefix)).map(entry -> prefix);
}
英文:

I have hash map which contains strings like a.01, a.02, b.01, b.02 and a list as value.

Now I would like to create a new map and put there as a key the prefix of the keys (like a, b,.. etc) and as value the content of the lists of the elements with similar prefix.

Example: group lists of prefix a and b 
input: Map&lt;String, List&gt; input = {(a.1,l1), (a.2,l2),(b.1,l3), (b.2,l4)}
Output: Map&lt;String, List&gt; output = {(a,{l1,l2}), (b,{l3,l4})}

I tried the following but it is not working

public static Set&lt;String&gt; prefixName(final Map&lt;String, List&gt; names, final String prefix) {
	    return names.entrySet().stream()
	        .filter(entry -&gt; entry.getKey().startsWith(prefix)).map(entry -&gt; prefix);
	}

答案1

得分: 1

这是命令式方法的示例代码:

public class Main {
    public static void main(String[] args) {
        Map<String, List<String>> originalMap = new HashMap<>();
        originalMap.put("a.1", Arrays.asList("l1"));
        originalMap.put("a.2", Arrays.asList("l2"));
        originalMap.put("b.1", Arrays.asList("l3"));
        originalMap.put("b.2", Arrays.asList("l4"));

        Map<String, List<String>> newMap = new HashMap<>();

        for (Map.Entry<String, List<String>> entry : originalMap.entrySet()) {
            String newKey = entry.getKey().split("\\.")[0];
            if (!newMap.containsKey(newKey)) {
                newMap.put(newKey, new ArrayList<>());
            }
            newMap.get(newKey).addAll(entry.getValue());
        }
        System.out.println(newMap);
    }
}

结果图如下:
将具有相同前缀入口键的映射值分组。

英文:

Try this imperative approach:

public class Main {
    public static void main(String[] args) {
        Map&lt;String, List&lt;String&gt;&gt; originalMap = new HashMap&lt;&gt;();
        originalMap.put(&quot;a.1&quot;,Arrays.asList(&quot;l1&quot;));
        originalMap.put(&quot;a.2&quot;,Arrays.asList(&quot;l2&quot;));
        originalMap.put(&quot;b.1&quot;,Arrays.asList(&quot;l3&quot;));
        originalMap.put(&quot;b.2&quot;,Arrays.asList(&quot;l4&quot;));

        Map&lt;String,List&lt;String&gt;&gt; newMap = new HashMap&lt;&gt;();

        for (Map.Entry&lt;String,List&lt;String&gt;&gt; entry: originalMap.entrySet()){
            String newKey = entry.getKey().split(&quot;\\.&quot;)[0];
            if(!newMap.containsKey(newKey)){
                newMap.put(newKey,new ArrayList&lt;&gt;());
            }
            newMap.get(newKey).addAll(entry.getValue());
        }
        System.out.println(newMap);
    }

Result:
将具有相同前缀入口键的映射值分组。

答案2

得分: 1

如果此任务不需要_streams_,您可以使用以下方法。

遍历原始映射,检查新映射是否包含_prefix_键。
然后,要么将列表添加到新映射列表中,要么创建新的映射条目。

Map&lt;String, List&lt;List&gt;&gt; parse(Map&lt;String, List&gt; mapA) {
    Map&lt;String, List&lt;List&gt;&gt; mapB = new HashMap&lt;&gt;();
    String prefix;
    List&lt;List&gt; lists;
    for (Map.Entry&lt;String, List&gt; entry : mapA.entrySet()) {
        prefix = prefix(entry.getKey());
        if (mapB.containsKey(prefix))
            mapB.get(prefix).add(entry.getValue());
        else {
            lists = new ArrayList&lt;&gt;();
            lists.add(entry.getValue());
            mapB.put(prefix, lists);
        }
    }
    return mapB;
}

另外,我在这里创建了一个方法,用于从_key_中提取_prefix_子串。
其中,我认为这可能比单独的子串更复杂。

String prefix(String string) {
    /* a.01, a.02, b.01, 等等。 */
    return string.substring(0, string.indexOf(&#39;.&#39;));
}

以下是输入和输出的示例。

Map&lt;String, List&gt; mapA = new HashMap&lt;&gt;();
mapA.put(&quot;a.01&quot;, List.of(1, 2, 3, 4));
mapA.put(&quot;a.02&quot;, List.of(5, 6, 7, 8));
mapA.put(&quot;b.01&quot;, List.of(9, 0, 1, 2));
mapA.put(&quot;b.02&quot;, List.of(3, 4, 5, 6));

Map&lt;String, List&lt;List&gt;&gt; mapB = parse(mapA);
System.out.println(mapB);
{a=[[1, 2, 3, 4], [5, 6, 7, 8]], b=[[9, 0, 1, 2], [3, 4, 5, 6]]}
英文:

If this task does not require streams, you can use the following.

Traverse the original map, checking if the new map contains the prefix key.
Then, either add the list to the new map list, or create a new map entry.

Map&lt;String, List&lt;List&gt;&gt; parse(Map&lt;String, List&gt; mapA) {
    Map&lt;String, List&lt;List&gt;&gt; mapB = new HashMap&lt;&gt;();
    String prefix;
    List&lt;List&gt; lists;
    for (Map.Entry&lt;String, List&gt; entry : mapA.entrySet()) {
        prefix = prefix(entry.getKey());
        if (mapB.containsKey(prefix))
            mapB.get(prefix).add(entry.getValue());
        else {
            lists = new ArrayList&lt;&gt;();
            lists.add(entry.getValue());
            mapB.put(prefix, lists);
        }
    }
    return mapB;
}

Additionally, I created a method here, to substring the prefix from the key.
In which, I presume may be more complicated than a single substring.

String prefix(String string) {
    /* a.01, a.02, b.01, etc. */
    return string.substring(0, string.indexOf(&#39;.&#39;));
}

Here is an example of an input and output.

Map&lt;String, List&gt; mapA = new HashMap&lt;&gt;();
mapA.put(&quot;a.01&quot;, List.of(1, 2, 3, 4));
mapA.put(&quot;a.02&quot;, List.of(5, 6, 7, 8));
mapA.put(&quot;b.01&quot;, List.of(9, 0, 1, 2));
mapA.put(&quot;b.02&quot;, List.of(3, 4, 5, 6));

Map&lt;String, List&lt;List&gt;&gt; mapB = parse(mapA);
System.out.println(mapB);
{a=[[1, 2, 3, 4], [5, 6, 7, 8]], b=[[9, 0, 1, 2], [3, 4, 5, 6]]}

答案3

得分: 1

如果你想以流的方式进行操作,你可以使用映射函数作为集合操作的一部分。这将允许创建一个多重映射,其中你的简化和减少的键会与该键的原始值(类型为List&lt;string&gt;)一起收集到一个封闭的List&lt;List&lt;String&gt;&gt;中:

import java.util.stream.*;
import static java.util.stream.Collectors.*;
import java.util.*;

public class Grouping {
    public static void main(String[] args) {
        try {
            List&lt;String&gt; l1 = List.of(&quot;foo&quot;, &quot;bar&quot;);
            List&lt;String&gt; l2 = List.of(&quot;goo&quot;, &quot;car&quot;);
            List&lt;String&gt; l3 = List.of(&quot;boo&quot;, &quot;par&quot;);
            List&lt;String&gt; l4 = List.of(&quot;loo&quot;, &quot;tar&quot;);

            Map&lt;String, List&lt;String&gt;&gt; mapped = Map.of(
                    &quot;a.1&quot;, l1,
                    &quot;a.2&quot;, l2,
                    &quot;b.1&quot;, l3,
                    &quot;b.2&quot;, l4);

            Map&lt;String, List&lt;List&lt;String&gt;&gt;&gt; grouped = mapped.entrySet().
                stream().
                collect(groupingBy(e -&gt;e.getKey().substring(0, 1), mapping(e -&gt;e.getValue(), toList())));
            System.out.println(grouped);
        }
        catch(Throwable t) {
            t.printStackTrace();
        }
    }
}

输出为:

{a=[[foo, bar], [goo, car]], b=[[boo, par], [loo, tar]]}
英文:

If you want to do it stream-wise you can use a mapping function as part of a collection operation. This will enable a multimap to be created with your simplified and reduced key, with the original values of that key (type List&lt;string&gt;) collected into an enclosing List&lt;List&lt;String&gt;&gt;:

import java.util.stream.*;
import static java.util.stream.Collectors.*;
import java.util.*;
public class Grouping {
public static void main(String[] args) {
try {
List&lt;String&gt; l1 = List.of(&quot;foo&quot;, &quot;bar&quot;);
List&lt;String&gt; l2 = List.of(&quot;goo&quot;, &quot;car&quot;);
List&lt;String&gt; l3 = List.of(&quot;boo&quot;, &quot;par&quot;);
List&lt;String&gt; l4 = List.of(&quot;loo&quot;, &quot;tar&quot;);
Map&lt;String, List&lt;String&gt;&gt; mapped = Map.of(
&quot;a.1&quot;, l1,
&quot;a.2&quot;, l2,
&quot;b.1&quot;, l3,
&quot;b.2&quot;, l4);
Map&lt;String, List&lt;List&lt;String&gt;&gt;&gt; grouped = mapped.entrySet().
stream().
collect(groupingBy(e -&gt;e.getKey().substring(0, 1), mapping(e -&gt;e.getValue(), toList())));
System.out.println(grouped);
}
catch(Throwable t) {
t.printStackTrace();
}
}
}

The output being:

{a=[[foo, bar], [goo, car]], b=[[boo, par], [loo, tar]]}

huangapple
  • 本文由 发表于 2023年6月6日 00:21:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76408303.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定