github.com/searKing/golang/go@v1.2.74/container/stream/op/while/drop_while_sink.go (about)

     1  // Copyright 2020 The searKing Author. 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 while
     6  
     7  import (
     8  	"github.com/searKing/golang/go/container/stream/op/terminal"
     9  	"github.com/searKing/golang/go/util/function/predicate"
    10  	"github.com/searKing/golang/go/util/optional"
    11  )
    12  
    13  /**
    14   * A specialization for a dropWhile sink.
    15   *
    16   * @param <T> the type of both input and output elements
    17   */
    18  type DropWhileSink interface {
    19  	terminal.Sink
    20  	/**
    21  	 * @return the could of elements that would have been dropped and
    22  	 * instead were passed downstream.
    23  	 */
    24  	GetDropCount() int
    25  }
    26  
    27  type dropWhileSink struct {
    28  	terminal.TODOSink
    29  	dropCount int
    30  	take      bool
    31  
    32  	retainAndCountDroppedElements bool
    33  	predicate                     predicate.Predicater
    34  }
    35  
    36  func NewDropWhileSink(retainAndCountDroppedElements bool, predicate predicate.Predicater) *dropWhileSink {
    37  	c := &dropWhileSink{
    38  		retainAndCountDroppedElements: retainAndCountDroppedElements,
    39  		predicate:                     predicate,
    40  	}
    41  	c.SetDerived(c)
    42  	return c
    43  }
    44  
    45  func (sink *dropWhileSink) Accept(t interface{}) {
    46  	if !sink.take {
    47  		sink.take = !sink.predicate.Test(t)
    48  	}
    49  	takeElement := sink.take
    50  
    51  	// If ordered and element is dropped increment index
    52  	// for possible future truncation
    53  	if sink.retainAndCountDroppedElements && !takeElement {
    54  		sink.dropCount++
    55  	}
    56  
    57  	// If ordered need to process element, otherwise
    58  	// skip if element is dropped
    59  	if sink.retainAndCountDroppedElements && takeElement {
    60  		sink.TODOSink.Accept(t)
    61  	}
    62  }
    63  
    64  func (sink *dropWhileSink) GetDropCount() int {
    65  	return sink.dropCount
    66  }
    67  
    68  func (sink *dropWhileSink) Get() optional.Optional {
    69  	return optional.Empty()
    70  }