简体   繁体   English

如何基于第一个元素合并多个数组列表?

[英]How to merge several list of arrays based on first element?

I have several lists of string arrays.我有几个字符串数组列表。 I would like to merge this lists in a single one based on the first element of each array.我想根据每个数组的第一个元素将此列表合并为一个列表。

Basically, I would like to merge this two list基本上,我想合并这两个列表

ArrayList<String[]> list1 = new ArrayList<String[]>();
list1.add(new String[]{"key1","a","a","a"});
list1.add(new String[]{"key2","a","a","a"});
list1.add(new String[]{"key4","a","a","a"});

ArrayList<String[]> list2 = new ArrayList<String[]>();
list2.add(new String[]{"key1","b","b"});
list2.add(new String[]{"key2","b","b"});
list2.add(new String[]{"key3","c","c"});

in this one在这个

[key4,a,a,a,null,null]
[key3,null,null,null,c,c]
[key2,a,a,a,b,b]
[key1,a,a,a,b,b]

Some more things :还有一些事情:

  • List order does not matter列表顺序无关紧要
  • Array order is important , so I have to add padding if value not present数组顺序很重要,所以如果值不存在,我必须添加填充

Does someone know an efficient way to do it ?有人知道一种有效的方法吗?

My current approach我目前的做法

My current approach use an HashMap to store the key (first element of the array)我目前的方法使用 HashMap 来存储键(数组的第一个元素)

HashMap<String, String[]> results = new HashMap<String, String[]>();
process(list1); 
process(list2); 

void process(ArrayList<String[]> list) {
    for(String[]s : list) {
        if(!results.containsKey(s[0])) {
            results.put(s[0], Arrays.copyOfRange(s, 1, s.length));
        } else {
            String[] current = results.get(s[0]);
            results.put(s[0], concat(current, Arrays.copyOfRange(s, 1, s.length)));
        }
    }
} 

which give me the ouput (incorrect because no "padding")这给了我输出(不正确,因为没有“填充”)

key4 [a, a, a]
key3 [c, c]
key2 [a, a, a, b, b]
key1 [a, a, a, b, b]

Basically, what you need to do, is check list2 if the desired key exists.基本上,您需要做的是检查list2是否存在所需的密钥。 If it does, simply merge the arrays.如果是,只需合并数组。 However, if the key is not present in list2 , you have to add a padded array.但是,如果 key 不存在于list2 ,则必须添加一个填充数组。 This can be done relatively easy by returning a new array with the desired length.这可以通过返回具有所需长度的新数组来相对容易地完成。

Have a look at my code below:看看我下面的代码:

public void mergeArrays() {

  ArrayList<String[]> list1 = new ArrayList<String[]>();
  list1.add(new String[] { "key1", "a", "a", "a" });
  list1.add(new String[] { "key2", "a", "a", "a" });
  list1.add(new String[] { "key4", "a", "a", "a" });

  ArrayList<String[]> list2 = new ArrayList<String[]>();
  list2.add(new String[] { "key1", "b", "b" });
  list2.add(new String[] { "key2", "b", "b" });
  list2.add(new String[] { "key3", "c", "c" });

  ArrayList<String[]> result = new ArrayList<String[]>();

  // Merge list1 to list2
  for (String[] array1: list1) {
     // Find key from list1 in list2
     int index = this.findIndex(array1[0], list2);

     // Key was found, merge arrays
     if (index > -1) {
        result.add(this.concat(array1, list2.get(index)));
     }
     // Key was not found, use padding
     else {
        // Padding second array with null values
        result.add(this.concat(array1, this.padding(list2.get(0).length, null)));
     }
  }

  // Merge list2 to list1
  for (String[] array2: list2) {
     // Find key from list2 in list1
     int index = this.findIndex(array2[0], list1);

     // Key was not found, use padding
     if (index == -1) {
        // Padding first array with null values
        String[] temp = this.concat(this.padding(list1.get(0).length, null), array2);
        temp[0] = array2[0]; // Set key
        result.add(temp);
     }
  }

  // Debug output
  for (String[] array: result) {
     for (int i = 0; i < array.length; ++i) {
        System.out.print(array[i] + " ");
     }
     System.out.println("");
  }
}

// Return array with padding
private String[] padding(final int size, final String padding) {
  String[] result = new String[size];
  Arrays.fill(result, padding);

  return result;
}

// Find needle in haystack and return index
private int findIndex(final String needle, final ArrayList<String[]> haystack) {
  for (int i = 0; i < haystack.size(); ++i) {
     if (haystack.get(i)[0].equals(needle)) {
        return i;
     }
  }

  return -1;
}

// Merge two arrays, omit first element of second array
private String[] concat(String[] arrayOne, String[] arrayTwo) {
  int arrayOneLength = arrayOne.length;
  int arrayTwoLength = arrayTwo.length;

  String[] result = new String[arrayOneLength + arrayTwoLength - 1];
  System.arraycopy(arrayOne, 0, result, 0, arrayOneLength);
  System.arraycopy(arrayTwo, 1, result, arrayOneLength, arrayTwoLength - 1); // Skip key in second array

  return result;
}

Output:输出:

key1 a a a b b
key2 a a a b b
key4 a a a null null
key3 null null null c c

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

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