github.com/tursom/GoCollections@v0.3.10/collections/Iterable.go (about)

     1  /*
     2   * Copyright (c) 2022 tursom. All rights reserved.
     3   * Use of this source code is governed by a GPL-3
     4   * license that can be found in the LICENSE file.
     5   */
     6  
     7  package collections
     8  
     9  import (
    10  	"github.com/tursom/GoCollections/exceptions"
    11  	"github.com/tursom/GoCollections/lang"
    12  )
    13  
    14  type (
    15  	// Iterator an iterator over a collection or another entity that can be represented as a sequence of elements.
    16  	// Allows to sequentially access the elements
    17  	Iterator[T any] interface {
    18  		// HasNext return true if the iterator has more elements
    19  		HasNext() bool
    20  		// Next returns the next element in the iteration
    21  		// return exceptions.IndexOutOfBound if there is no more element
    22  		Next() (T, exceptions.Exception)
    23  	}
    24  
    25  	// MutableIterator an iterator over a mutable collection.
    26  	// Provides the ability to remove elements while iterating.
    27  	MutableIterator[T any] interface {
    28  		Iterator[T]
    29  		// Remove removes from the underlying collection the last element returned by this iterator.
    30  		Remove() exceptions.Exception
    31  	}
    32  
    33  	// ListIterator an iterator over a collection that supports indexed access
    34  	ListIterator[T any] interface {
    35  		Iterator[T]
    36  		HasPrevious() bool
    37  		Previous() (T, exceptions.Exception)
    38  		NextIndex() int
    39  		PreviousIndex() int
    40  	}
    41  
    42  	// MutableListIterator an iterator over a mutable collection that supports indexed access
    43  	// Provides the ability to add, modify and remove elements while iterating.
    44  	MutableListIterator[T any] interface {
    45  		ListIterator[T]
    46  		MutableIterator[T]
    47  		Set(value T) exceptions.Exception
    48  		Add(value T) exceptions.Exception
    49  	}
    50  
    51  	// Iterable classes that inherit from this interface can be represented as a sequence of elements that can be iterated over.
    52  	// param T
    53  	Iterable[T any] interface {
    54  		Iterator() Iterator[T]
    55  	}
    56  
    57  	MutableIterable[T any] interface {
    58  		Iterable[T]
    59  		MutableIterator() MutableIterator[T]
    60  	}
    61  )
    62  
    63  func Loop[T any](iterable Iterable[T], f func(element T) exceptions.Exception) exceptions.Exception {
    64  	if f == nil || iterable == nil {
    65  		return exceptions.NewNPE("", nil)
    66  	}
    67  	return LoopIterator(iterable.Iterator(), f)
    68  }
    69  
    70  func LoopMutable[T any](
    71  	iterable MutableIterable[T],
    72  	f func(element T, iterator MutableIterator[T]) (err exceptions.Exception),
    73  ) exceptions.Exception {
    74  	if f == nil || iterable == nil {
    75  		return exceptions.NewNPE("", nil)
    76  	}
    77  	return LoopMutableIterator(iterable.MutableIterator(), f)
    78  }
    79  
    80  func LoopIterator[T any](iterator Iterator[T], f func(element T) exceptions.Exception) exceptions.Exception {
    81  	if f == nil || iterator == nil {
    82  		return exceptions.NewNPE("", nil)
    83  	}
    84  	for iterator.HasNext() {
    85  		next, err := iterator.Next()
    86  		if err != nil {
    87  			return err
    88  		}
    89  		err = f(next)
    90  		if err != nil {
    91  			return err
    92  		}
    93  	}
    94  	return nil
    95  }
    96  
    97  func LoopMutableIterator[T any](
    98  	iterator MutableIterator[T],
    99  	f func(element T, iterator MutableIterator[T]) (err exceptions.Exception),
   100  ) exceptions.Exception {
   101  	if f == nil || iterator == nil {
   102  		return exceptions.NewNPE("", nil)
   103  	}
   104  	for iterator.HasNext() {
   105  		next, err := iterator.Next()
   106  		if err != nil {
   107  			return err
   108  		}
   109  		err = f(next, iterator)
   110  		if err != nil {
   111  			return err
   112  		}
   113  	}
   114  	return nil
   115  }
   116  
   117  func Size[T any](iterable Iterable[T]) (size int, err exceptions.Exception) {
   118  	iterator := iterable.Iterator()
   119  	for iterator.HasNext() {
   120  		_, err = iterator.Next()
   121  		if err != nil {
   122  			return
   123  		}
   124  		size++
   125  	}
   126  	return
   127  }
   128  
   129  func Contains[T lang.Object](l Iterable[T], element T) bool {
   130  	return Loop(l, func(e T) exceptions.Exception {
   131  		if lang.Equals(element, e) {
   132  			return exceptions.ElementFound
   133  		}
   134  		return nil
   135  	}) != nil
   136  }
   137  
   138  func Remove[T lang.Object](l MutableIterable[T], element T) exceptions.Exception {
   139  	return LoopMutable(l, func(e T, iterator MutableIterator[T]) (err exceptions.Exception) {
   140  		if lang.Equals(element, e) {
   141  			return iterator.Remove()
   142  		}
   143  		return nil
   144  	})
   145  }
   146  
   147  func RemoveAll[T any](l MutableIterable[T], collection Collection[T]) bool {
   148  	return LoopMutable(l, func(element T, iterator MutableIterator[T]) (err exceptions.Exception) {
   149  		if collection.Contains(element) {
   150  			return iterator.Remove()
   151  		}
   152  		return nil
   153  	}) == nil
   154  }
   155  
   156  func RetainAll[T any](l MutableIterable[T], collection Collection[T]) bool {
   157  	return LoopMutable(l, func(element T, iterator MutableIterator[T]) exceptions.Exception {
   158  		if !collection.Contains(element) {
   159  			return iterator.Remove()
   160  		}
   161  		return nil
   162  	}) == nil
   163  }
   164  
   165  func Clear[T any](l MutableIterable[T]) exceptions.Exception {
   166  	return LoopMutable(l, func(element T, iterator MutableIterator[T]) (err exceptions.Exception) {
   167  		return iterator.Remove()
   168  	})
   169  }
   170  
   171  // SkipIterator skip [skip] items of [iterator]
   172  // returns [iterator] itself
   173  func SkipIterator[T any](iterator Iterator[T], skip int) (Iterator[T], exceptions.Exception) {
   174  	for i := 0; i < skip; i++ {
   175  		if iterator.HasNext() {
   176  			_, err := iterator.Next()
   177  			if err != nil {
   178  				return nil, err
   179  			}
   180  		} else {
   181  			break
   182  		}
   183  	}
   184  	return iterator, nil
   185  }