从列表中移除基于另一个列表中重复索引的重复项。

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

Remove duplicates from list based on duplicate index in another list

问题

我有两个列表:NamesIDs

有时同一个名称会出现多次。例如:

Names = {'ben','david','jerry','tom','ben'}
IDs   = {'123','23456','34567','123','123'}

我知道我可以使用:

Set<String> set = new LinkedHashSet<>(Names);
Names.clear();
Names.addAll(set);

为了去除重复项,但这不是我想要的。

我想要做的是检查 Names 是否有重复值,这种情况下将是最后一个值,然后从 IDs 中删除该位置上的值,最终结果将是:

Names = {'ben','david','jerry','tom'}
IDs   = {'123','23456','34567','123'}

如何获得重复值的索引以便从第二个列表中删除它?或者是否有某种简单快速的方法来做到这一点?

我确信我可以通过使用循环来解决,但我尝试避免这样做。

解决方案:

我更改了代码使用:

Map<String, String> map = new HashMap<>();

当使用:

map.put(name,id);

可能无法完成任务,因为同一个名称有不同的 id,它不会允许名称重复,所以我改为 map.put(id,name),这就完成了任务。

谢谢

英文:

I have 2 Lists: Names & IDs.

There are cases where the same name will appear multiple times. For example:

Names = {&#39;ben&#39;,&#39;david&#39;,&#39;jerry&#39;,&#39;tom&#39;,&#39;ben&#39;}
IDs   = {&#39;123&#39;,&#39;23456&#39;,&#39;34567&#39;,&#39;123&#39;,&#39;123&#39;}

I know I can use

Set&lt;String&gt; set = new LinkedHashSet&lt;&gt;( Names );
Names .clear();
Names .addAll( set );

In order to remove duplicates, however, it not what I want.

What I would like to do is to check where Names has a duplicate value which in this case will be the last value and then remove from IDs the value at that position so the final result will be:

Names = {&#39;ben&#39;,&#39;david&#39;,&#39;jerry&#39;,&#39;tom&#39;}
IDs   = {&#39;123&#39;,&#39;23456&#39;,&#39;34567&#39;,&#39;123&#39;}

How can I get the index of the duplicated value in order to remove it from the second list? or is there some easy and fast way to do it?

I'm sure I can solve it by using a loop but I try to avoid it.

SOLUTION:

I changed the code to use:

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

When using:

map.put(name,id);

It might not do the job since there are cases where the same name has different it and it won't allow duplicate in the name so just changed to map.put(id,name) and it did the job.

Thank you

答案1

得分: 3

你可以将两个输入的数组/列表的数据收集到一组配对中,然后重新收集这些配对到两个新的数组/列表中(或清空并重用现有的 names/IDs 数组/列表):

List<String> names = Arrays.asList("ben", "david", "jerry", "tom", "ben");
List<String> IDs   = Arrays.asList("123", "23456", "34567", "123", "123");

// 假设两个列表的大小相同
// 使用列表存储一对配对
Set<List<String>> deduped = IntStream.range(0, names.size())
                 .mapToObj(i -> Arrays.asList(names.get(i), IDs.get(i)))
                 .collect(Collectors.toCollection(LinkedHashSet::new));

System.out.println(deduped);
System.out.println("-------");

List<String> dedupedNames = new ArrayList<>();
List<String> dedupedIDs = new ArrayList<>();
deduped.forEach(pair -> {dedupedNames.add(pair.get(0)); dedupedIDs.add(pair.get(1)); });

System.out.println(dedupedNames);
System.out.println(dedupedIDs);

输出结果:

[[ben, 123], [david, 23456], [jerry, 34567], [tom, 123]]
-------
[ben, david, jerry, tom]
[123, 23456, 34567, 123]
英文:

You could collect the data from both input arrays/lists into a set of pairs and then recollect the pairs back to two new lists (or clear and reuse existing names/IDs lists):

List&lt;String&gt; names = Arrays.asList(&quot;ben&quot;,&quot;david&quot;,&quot;jerry&quot;,&quot;tom&quot;,&quot;ben&quot;);
List&lt;String&gt; IDs   = Arrays.asList(&quot;123&quot;,&quot;23456&quot;,&quot;34567&quot;,&quot;123&quot;,&quot;123&quot;);

// assuming that both lists have the same size
// using list to store a pair
Set&lt;List&lt;String&gt;&gt; deduped = IntStream.range(0, names.size())
                 .mapToObj(i -&gt; Arrays.asList(names.get(i), IDs.get(i)))
                 .collect(Collectors.toCollection(LinkedHashSet::new));

System.out.println(deduped);
System.out.println(&quot;-------&quot;);

List&lt;String&gt; dedupedNames = new ArrayList&lt;&gt;();
List&lt;String&gt; dedupedIDs = new ArrayList&lt;&gt;();
deduped.forEach(pair -&gt; {dedupedNames.add(pair.get(0)); dedupedIDs.add(pair.get(1)); });

System.out.println(dedupedNames);
System.out.println(dedupedIDs);

Output:

[[ben, 123], [david, 23456], [jerry, 34567], [tom, 123]]
-------
[ben, david, jerry, tom]
[123, 23456, 34567, 123]

答案2

得分: 1

你可以使用 Collectors.toMap 以 map 的形式收集数据,然后从 map 中获取 keySet 和 values,用于 names 和 ids 列表。

List<String> names = Arrays.asList("ben", "david", "jerry", "tom", "ben");
List<String> ids = Arrays.asList("123", "23456", "34567", "123", "123");
Map<String, String> map = 
          IntStream.range(0, ids.size())
                   .boxed()
                   .collect(Collectors.toMap(i -> names.get(i), i -> ids.get(i),
                                             (a, b) -> a, LinkedHashMap::new));
List<String> newNames = new ArrayList<>(map.keySet());
List<String> newIds = new ArrayList<>(map.values());

你也可以使用循环创建 map 部分:

Map<String, String> map = new LinkedHashMap<>();
for (int i = 0; i < names.size(); i++) {
  if (!map.containsKey(names.get(i))) {
    map.put(names.get(i), ids.get(i));
  }
}
英文:

You can collect as a map using Collectors.toMap then get the keySet and values from map for names and ids list.

List&lt;String&gt; names = Arrays.asList(&quot;ben&quot;,&quot;david&quot;,&quot;jerry&quot;,&quot;tom&quot;,&quot;ben&quot;);
List&lt;String&gt; ids   = Arrays.asList(&quot;123&quot;,&quot;23456&quot;,&quot;34567&quot;,&quot;123&quot;,&quot;123&quot;);
Map&lt;String, String&gt; map = 
          IntStream.range(0, ids.size())
                   .boxed()
                   .collect(Collectors.toMap(i -&gt; names.get(i), i -&gt; ids.get(i),
                                             (a,b) -&gt; a, LinkedHashMap::new));
List&lt;String&gt; newNames = new ArrayList&lt;&gt;(map.keySet());
List&lt;String&gt; newIds = new ArrayList&lt;&gt;(map.values());

You can do map creation part using loop also

Map&lt;String, String&gt; map = new LinkedHashMap&lt;&gt;();
for (int i = 0; i &lt; names.size(); i++) {
  if(!map.containsKey(names.get(i))) {
    map.put(names.get(i), ids.get(i));
  }
}

答案3

得分: 1

你可以逐个将你们的名字添加到一个集合中,只要 Set.add 返回 true,如果返回 false,则将该元素的索引存储在一个列表中(要移除的索引)。然后,以逆序方式对索引列表进行排序,并在你们的名字列表和 id 列表上使用 List.remove(int n)

List<String> names = ...
List<String> ids = ...
Set<String> set = new HashSet<>();
List<Integer> toRemove = new ArrayList<>();

for (int i = 0; i < names.size(); i++) {
    if (!set.add(names.get(i))) {
        toRemove.add(i);
    }
}

Collections.sort(toRemove, Collections.reverseOrder());
for (int i : toRemove) {
    names.remove(i);  
    ids.remove(i);
}

System.out.println(toRemove);

System.out.println(names);
System.out.println(ids);
英文:

You could add your names one by one to a set as long as Set.add returns true and if it returns false store the index of that element in a list (indices to remove). Then sort the indices list in reverse order and use List.remove(int n) on both your names list and id list:

List&lt;String&gt; names = ...
List&lt;String&gt; ids = ...
Set&lt;String&gt; set = new HashSet&lt;&gt;();
List&lt;Integer&gt; toRemove = new ArrayList&lt;&gt;();

for(int i = 0; i&lt; names.size(); i ++){
    if(!set.add(names.get(i))){
        toRemove.add(i);
    }
}

Collections.sort(toRemove, Collections.reverseOrder());
for (int i : toRemove){
    names.remove(i);  
    ids.remove(i);
}

System.out.println(toRemove);

System.out.println(names);
System.out.println(ids);

huangapple
  • 本文由 发表于 2020年10月1日 20:12:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/64155164.html
匿名

发表评论

匿名网友

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

确定