golang中是否有任何函数会发现值是否在数组中?

时间:2018-10-24 09:23:29

标签: arrays loops go slice

假设其中有一个包含整数的切片。并且我们已经声明了一个包含整数值的变量,然后我必须在不使用for循环的情况下从该片中查找值。

使用循环,我喜欢这样:-

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

public class ExcelReaderDemo {
public static final String SAMPLE_XLSX_FILE_PATH = 
   "C:/XLXSToDocx/Roaster.xlsm";
public static final String FILE_PATH ="C:/XLXSToDocx/writeExcel.docx";

public static void main(String[] args) throws IOException, 
InvalidFormatException {
    Workbook workbook = WorkbookFactory.create(new 
File(SAMPLE_XLSX_FILE_PATH));

    System.out.println("Workbook has " + workbook.getNumberOfSheets() + " 
Sheets : ");

    Sheet sheet = workbook.getSheetAt(0);
    DataFormatter dataFormatter = new DataFormatter();

    Iterator<Row> rowIterator = sheet.rowIterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        Iterator<Cell> cellIterator = row.cellIterator();

        while (cellIterator.hasNext()) {
            Cell cell = cellIterator.next();
            String cellValue = dataFormatter.formatCellValue(cell);
            System.out.print(cellValue + "\t");
        }

        try {

            FileOutputStream fos = new FileOutputStream(FILE_PATH);

            workbook.write(fos);

            fos.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

        System.out.println();
    }
    workbook.close();
}

我们如何不使用for循环来做同样的事情

1 个答案:

答案 0 :(得分:3)

没有for循环,没有 * (请参阅How to search for an element in a golang slice),但是...您对for循环有什么看法?为什么不能为此使用循环?这个问题就像“我可以不编码就可以做到吗?”

*实际上,您可以使用递归函数在没有for循环的情况下做到这一点,但这仅对教育有用,对实践目的毫无用处。请参阅答案末尾的解决方案。

在标准库中没有为此准备好的功能,但是这很容易自己创建:

func find(what interface{}, where []interface{}) (idx int) {
    for i, v := range where {
        if v == what {
            return i
        }
    }
    return -1
}

并使用它:

what := 10
where := []interface{}{1, 2, 3, 10, 5}
fmt.Println(find(what, where))

输出(在Go Playground上尝试):

3

还要注意,使用[]int切片类型而不是[]interface{}会更快,更方便:

func find(what int, where []int) (idx int) {
    for i, v := range where {
        if v == what {
            return i
        }
    }
    return -1
}

然后使用它:

what := 10
where := []int{1, 2, 3, 10, 5}
fmt.Println(find(what, where))

输出是相同的。在Go Playground上尝试这个。

您可以创建一个函数,该函数使用interface{}类型接受任何类型的切片,但是这需要进行反射才能实现,这会更慢并且不值得使用。而是根据需要使用具体的切片类型创建一个函数,或者就地使用for循环。

出于完整性考虑,以下是不使用for循环而是使用递归函数的解决方案。这仅出于教育目的,上述解决方案优于此:

func find(what int, where []int) (idx int) {
    if len(where) == 0 {
        return -1
    }
    if what == where[0] {
        return 0
    }
    if idx = find(what, where[1:]); idx < 0 {
        return -1 // Not found in the rest of the slice
    }
    return 1 + idx
}

Go Playground上尝试这个。