github.com/kazu/loncha@v0.6.3/find.go (about)

     1  // Copyright 2019 Kazuhisa TAKEI<xtakei@rytr.jp>. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package finder for slice.
     6  //
     7  // To Find from slice: (list is slice)
     8  //   loncha.Find(&list, func(i int) {
     9  //	 	return list[i].ID == 555
    10  //}
    11  
    12  package loncha
    13  
    14  // Find is value of slice if fn is true. if slice is not pointer of slice or empty, return error
    15  func Find(slice interface{}, fn CondFunc) (interface{}, error) {
    16  
    17  	idx, err := IndexOf(slice, fn)
    18  	if err != nil {
    19  		return nil, err
    20  	}
    21  
    22  	rv, _ := sliceElm2Reflect(slice)
    23  
    24  	return rv.Index(idx).Interface(), nil
    25  
    26  }
    27  
    28  // IndexOf gets the index at which the first match fn is true. if not found. return -1.
    29  // return error if slice is not pointer of the slice.
    30  func IndexOf(slice interface{}, fn CondFunc) (int, error) {
    31  
    32  	rv, err := sliceElm2Reflect(slice)
    33  	if err != nil {
    34  		return -1, err
    35  	}
    36  
    37  	length := rv.Len()
    38  	if length == 0 {
    39  		return -1, err
    40  	}
    41  	for i := 0; i < length; i++ {
    42  		if fn(i) {
    43  			return i, nil
    44  		}
    45  	}
    46  	return -1, ERR_NOT_FOUND
    47  }
    48  
    49  // LastIndexOf gets the last index at which the last match fn is true. if not found. return -1.
    50  // return error if slice is not pointer of the slice.
    51  func LastIndexOf(slice interface{}, fn CondFunc) (int, error) {
    52  
    53  	rv, err := sliceElm2Reflect(slice)
    54  	if err != nil {
    55  		return -1, err
    56  	}
    57  
    58  	length := rv.Len()
    59  	if length == 0 {
    60  		return -1, err
    61  	}
    62  	for i := length - 1; i >= 0; i-- {
    63  		if fn(i) {
    64  			return i, nil
    65  		}
    66  	}
    67  	return -1, ERR_NOT_FOUND
    68  }
    69  
    70  // Contain get return true which fn condition is true.
    71  func Contain(slice interface{}, fn CondFunc) bool {
    72  
    73  	idx, err := IndexOf(slice, fn)
    74  	if err != nil {
    75  		return false
    76  	}
    77  	if idx < 0 {
    78  		return false
    79  	}
    80  
    81  	return true
    82  
    83  }