( origStart: List<A>, firstMiss: List<A>, predicate: Predicate<A>, isFlipped: boolean )
| 538 | |
| 539 | // we have seen elements that should be included then one that should be excluded, start building |
| 540 | const partialFill = <A>( |
| 541 | origStart: List<A>, |
| 542 | firstMiss: List<A>, |
| 543 | predicate: Predicate<A>, |
| 544 | isFlipped: boolean |
| 545 | ): List<A> => { |
| 546 | const newHead = makeCons<A>(unsafeHead(origStart)!, _Nil) |
| 547 | let toProcess = unsafeTail(origStart)! as Cons<A> |
| 548 | let currentLast = newHead |
| 549 | |
| 550 | // we know that all elements are :: until at least firstMiss.tail |
| 551 | while (!(toProcess === firstMiss)) { |
| 552 | const newElem = makeCons(unsafeHead(toProcess)!, _Nil) |
| 553 | currentLast.tail = newElem |
| 554 | currentLast = unsafeCoerce(newElem) |
| 555 | toProcess = unsafeCoerce(toProcess.tail) |
| 556 | } |
| 557 | |
| 558 | // at this point newHead points to a list which is a duplicate of all the 'in' elements up to the first miss. |
| 559 | // currentLast is the last element in that list. |
| 560 | |
| 561 | // now we are going to try and share as much of the tail as we can, only moving elements across when we have to. |
| 562 | let next = firstMiss.tail |
| 563 | let nextToCopy: Cons<A> = unsafeCoerce(next) // the next element we would need to copy to our list if we cant share. |
| 564 | while (!isNil(next)) { |
| 565 | // generally recommended is next.isNonEmpty but this incurs an extra method call. |
| 566 | const head = unsafeHead(next)! |
| 567 | if (predicate(head) !== isFlipped) { |
| 568 | next = next.tail |
| 569 | } else { |
| 570 | // its not a match - do we have outstanding elements? |
| 571 | while (!(nextToCopy === next)) { |
| 572 | const newElem = makeCons(unsafeHead(nextToCopy)!, _Nil) |
| 573 | currentLast.tail = newElem |
| 574 | currentLast = newElem |
| 575 | nextToCopy = unsafeCoerce(nextToCopy.tail) |
| 576 | } |
| 577 | nextToCopy = unsafeCoerce(next.tail) |
| 578 | next = next.tail |
| 579 | } |
| 580 | } |
| 581 | |
| 582 | // we have remaining elements - they are unchanged attach them to the end |
| 583 | if (!isNil(nextToCopy)) { |
| 584 | currentLast.tail = nextToCopy |
| 585 | } |
| 586 | return newHead |
| 587 | } |
| 588 | |
| 589 | /** |
| 590 | * Filters and maps a list using the specified partial function. The resulting |
no test coverage detected