Tip: This series is for readers with other phonetic roots and a persistent urge to Go

I. Snooping on Map and input mode

In Python you can use dict to do statistics on characters, and in Go you have a similar data structure map.

A map stores sets of keys and values, and provides constant time store, fetch, or test operations on set elements. Keys can be of any type, as long as their values can be compared using the == operator, the most common example being strings; The value can be of any type. The keys in this example are strings and the values are integers.

1. Use standard inputbufioPacket read data
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main(a) {
	counts := make(map[string]int) // Create an empty map
	input_data := bufio.NewScanner(os.Stdin)
	for i := 0; i < 5; i++ {
		input_data.Scan()
		counts[input_dat  a.Text()]++
	}
	for index, value := range counts {   // Navigate through the map through range
		fmt.Printf("%s\t%d\n", index, value)
	}
}
Copy the code

Bufio package, which makes processing inputs and outputs easy and efficient. The Scanner type is one of the package’s most useful features, reading input and breaking it up into lines or words; Is usually the easiest way to handle input in line form.

The order of the map iteration through range is random. This design is intentional, because it prevents the program from relying on a specific traversal order, which will be further studied here.


2. Read data from files
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main(a) {

	file := os.Args[1:]
	counts := make(map[string]int) // Create an empty map
	if len(file) == 0 {   // Call the standard input function when there are no file arguments
		countline(counts)  // Pass a copy of counts
	} else {
		for _, arg := range file {
			f, err := os.Open(arg)
			iferr ! =nil {
				fmt.Println(os.Stderr)
				continue
			}
			read_file(f, counts)  // Pass in a copy of the file and counts}}for index, value := range counts {    // Prints lines and statistics
		fmt.Printf("%s\t%d\n", index, value)  // C prinf function}}// Read the file, pass in an open file, map type parameter counts
func read_file(f *os.File, counts map[string]int) {  
	input := bufio.NewScanner(f)
	for input.Scan() {  //Scan searches the next line of the file
		counts[input.Text()]++
	}
}
func countline(counts map[string]int) {

	input_data := bufio.NewScanner(os.Stdin)
	for i := 0; i < 5; i++ {
		input_data.Scan()
		counts[input_data.Text()]++
	}

}

// myfile
[root@VM0- 5-centos course2]# cat myfile 
aaa
bbb
aaa
ccc
ddd

//output
[root@VM0- 5-centos course2]# go run counts.go  myfile
ddd     1
aaa     2
bbb     1
ccc     1
Copy the code

When a map is passed to a function as an argument, the function receives a copy of the reference, and any changes made by the called function to the map’s underlying data structure are visible to the caller through the holding map reference. Read_file and countline make changes to counts that can be detected by Main. In other languages, you might need to return data.

The FMT.Printf function in Go provides the output formatting capability of prinf in the C-like language.

%d decimal integer %x, % O, % B Hex, octal, binary integer. %f, %g, %e float: 3.141593 3.141592653589793 3.141593e+00 %t True or False % C character (rune) (Unicode code point) % S string %q The double quoted string "ABC" or the single quoted character 'c' %v The natural format of the variable %T The type of the variable %% Literal percent sign (no operands)Copy the code

3. Read the file using ReadFile

ReadFile reads everything at once. The ReadFile function returns a byte slice, which must be converted to a string and Split by strings.split.

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

func main(a) {
	counts := make(map[string]int) // Create an empty map
	for _, filename := range os.Args[1:] {
		data, err := ioutil.ReadFile(filename)
		iferr ! =nil {
			fmt.Println(os.Stderr, "%v", err)
			continue
		}
		//fmt.Println(string(data))
		for _, line := range strings.Split(string(data), "\n") {
			if len(line) > 0 {
				counts[line]++
			}
		}
		output(counts)
	}

}
func output(counts map[string]int) {
	for index, value := range counts {
		fmt.Printf("%s\t%d\n", index, value)
	}
}

//output
[root@VM0- 5-centos course2]# go run ioutil.go myfile
aaa     2
bbb     1
ccc     1
ddd     1
Copy the code

Bufio. Scanner, ioutil.ReadFile, and ioutil.WriteFile all use the Read and Write methods of *os.File, but most programmers rarely need to call those lower-level functions directly. Higher-level functions, such as those provided in the Bufio and IO /ioutil packages, are easier to use.


Second, the practice

Exercise 1.4: Modify the code to print the file name when duplicate lines appear.

Adjust the output function as follows.

func output(counts map[string]int) {
	for index, value := range counts {
        if value >=2{
            fmt.Printf("filename:%s %s\t%d\n", os.Args[0],index, value)    
        }else{
        	fmt.Printf("%s\t%d\n", index, value)    
        }
		
	}
}

//output
[root@VM0- 5-centos course2]# go run ioutil.go myfile
bbb     1
ccc     1
ddd     1
filename:/tmp/go-build303515636/b001/exe/ioutil aaa     2
Copy the code

Book reference: Go Language Bible In Chinese

Feel free to point out any shortcomings in the comments section.

Favorites, likes and questions are welcome. Follow the top water cooler managers and do something other than pipe hot water.