如何从数组中移除“null”元素?

5

我目前正在进行一个编码挑战,其要求如下:

给定一个单词列表,返回可以使用美式键盘上的一行字母键入的单词,如下图所示(这是一个QWERTY键盘的图像)。

例如:

Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]

我为解决这个问题所做的是编写一个for循环,然后使用if语句将所有行(如QWERTY)替换为"",如果长度大于1,则无法在一行中输入该单词。我几乎得到了正确的输出,但我的数组包含空元素。
我的输出是:
[null,"Alaska","Dad",null]

如何返回一个没有空元素的数组? 为了完成这个挑战,我需要返回一个String[]数组。我不能使用ArrayList来返回。

class Solution {
    public String[] findWords(String[] words) {
    String[] result = new String[words.length];

    String row1 = "qwertyuiop";
    String row2 = "asdfghjkl";
    String row3 = "zxcvbnm";

    for (int i = 0 ; i < words.length; i++) {
        if (words[i].toLowerCase().replaceAll("[" + row1 + "]", "").length() == 0 ||
           words[i].toLowerCase().replaceAll("[" + row2 + "]", "").length() == 0 ||
           words[i].toLowerCase().replaceAll("[" + row3 + "]", "").length() == 0) {
            if (words[i] != null) {
                result[i] = words[i];
            }


        }
       }

    return result;
    }


}

请使用Lambda过滤数组,将 https://dev59.com/oWAf5IYBdhLWcg3w9Wiu 中的“i > 0”替换为“i != null”。 - leonardkraemer
7个回答

6

使用这个一行代码:

Arrays.stream(result).filter(Objects::nonNull).toArray(String[]::new)

筛选数组并获取所有非空对象。不要忘记将流转换回数组。


4
您可以使用以下代码从字符串数组中删除所有空值:
List<String> list = new ArrayList<String>(Arrays.asList(myArray));
list.removeAll(Collections.singleton(null));
String[] result = list.toArray(new String[list.size()]);

2
原问题是您返回的Array与原始Array大小相同。因此,如果任何元素不匹配,则Array中的一个插槽将保留其默认值,即null。您需要跟踪需要复制的项目数量。您可以使用计数器和Arrays.copyOf()来实现此目的。
只是为了说明一下,在Java 8+中,我们可以这样做:
public static String[] findWords(String[] words) {
    return Stream.of("asdfghjkl", "qwertyuiop", "zxcvbnm")
                 .filter(row -> Arrays.stream(words)
                           .anyMatch(e -> e.replaceAll("[" + row + "]","")                  
                           .isEmpty())
                 ).toArray(String[]::new);
}

这段话的意思是:使用Stream.of创建一个行的Stream,并通过筛选words数组中仅由键盘上单个行字母组成的单词。

1
你可以使用 ArrayList 而不是数组,并在最后调用 toArray 方法,如果你真的需要返回一个字符串数组。
    public String[] findWords(String[] words) {
        List<String> result = new ArrayList<>();

        String row1 = "qwertyuiop";
        String row2 = "asdfghjkl";
        String row3 = "zxcvbnm";

        for (int i = 0; i < words.length; i++) {
            if (words[i].toLowerCase().replaceAll("[" + row1 + "]", "").length() == 0 ||
                    words[i].toLowerCase().replaceAll("[" + row2 + "]", "").length() == 0 ||
                    words[i].toLowerCase().replaceAll("[" + row3 + "]", "").length() == 0) {
                if (words[i] != null) {
                    result.add(words[i]);
                }
            }
        }

        return result.toArray(new String[0]);
    }

0

您的结果数组已经初始化为单词数组的大小。您可以使用ArrayList进行动态分配。

之后,您可以返回ArrayList的toArray方法,以便返回所需的字符串数组。

如果您不允许在代码中使用ArrayList,我建议您寻找如何动态调整结果数组大小的方法。


0
一种减小具有空元素数组大小的方法是使用 .filter() 方法。该方法将遍历数组的每个元素并检查其是否不为空。如果不为空,则将该元素添加到新数组中。然后返回新数组,其中仅包含非空元素。

0
尝试将非空值存储在另一个变量中并计数,使用计数初始化另一个数组,并将值复制到后者数组中。演示如下:
class Solution {
    public static String[] findWords(String[] words) {
    String[] resultWithNull = new String[words.length];
    int counter = 0;

    String row1 = "qwertyuiop";
    String row2 = "asdfghjkl";
    String row3 = "zxcvbnm";

    for (int i = 0 ; i < words.length; i++) {
      if (words[i].toLowerCase().replaceAll("[" + row1 + "]", "").length() == 0 ||
        words[i].toLowerCase().replaceAll("[" + row2 + "]", "").length() == 0 ||
        words[i].toLowerCase().replaceAll("[" + row3 + "]", "").length() == 0) {
        if (words[i] != null) {
         resultWithNull[counter] = words[i];
         ++counter;
       }
     }
   }

   String[] result = new String[counter];
   for (int i = 0 ; i < counter; i++) {
      result[i] = resultWithNull[i];
   }
   return result;
 }

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接