IsOrdered succeeds if every element is not less than the previous element as defined on the given `less` comparator function. For default, it will use built-in comparator function for each data type. Built-in comparator requires all elements in the array to have same data type. Array with 0 or 1 ele
(less ...func(x, y *Value) bool)
| 1558 | // return x.Number().Raw() < y.Number().Raw() |
| 1559 | // }) // succeeds |
| 1560 | func (a *Array) IsOrdered(less ...func(x, y *Value) bool) *Array { |
| 1561 | opChain := a.chain.enter("IsOrdered()") |
| 1562 | defer opChain.leave() |
| 1563 | |
| 1564 | if opChain.failed() { |
| 1565 | return a |
| 1566 | } |
| 1567 | |
| 1568 | if len(less) > 1 { |
| 1569 | opChain.fail(AssertionFailure{ |
| 1570 | Type: AssertUsage, |
| 1571 | Errors: []error{ |
| 1572 | errors.New("unexpected multiple less arguments"), |
| 1573 | }, |
| 1574 | }) |
| 1575 | return a |
| 1576 | } |
| 1577 | |
| 1578 | var lessFn func(x, y *Value) bool |
| 1579 | if len(less) == 1 { |
| 1580 | lessFn = less[0] |
| 1581 | if lessFn == nil { |
| 1582 | opChain.fail(AssertionFailure{ |
| 1583 | Type: AssertUsage, |
| 1584 | Errors: []error{ |
| 1585 | errors.New("unexpected nil less argument"), |
| 1586 | }, |
| 1587 | }) |
| 1588 | return a |
| 1589 | } |
| 1590 | } else { |
| 1591 | lessFn = builtinComparator(opChain, a.value) |
| 1592 | if lessFn == nil { |
| 1593 | return a |
| 1594 | } |
| 1595 | } |
| 1596 | |
| 1597 | if len(a.value) <= 1 { |
| 1598 | return a |
| 1599 | } |
| 1600 | |
| 1601 | for i := 0; i < len(a.value)-1; i++ { |
| 1602 | var unordered bool |
| 1603 | |
| 1604 | func() { |
| 1605 | xChain := opChain.replace("IsOrdered[%d]", i) |
| 1606 | defer xChain.leave() |
| 1607 | |
| 1608 | yChain := opChain.replace("IsOrdered[%d]", i+1) |
| 1609 | defer yChain.leave() |
| 1610 | |
| 1611 | x := newValue(xChain, a.value[i]) |
| 1612 | y := newValue(yChain, a.value[i+1]) |
| 1613 | |
| 1614 | unordered = lessFn(y, x) |
| 1615 | }() |
| 1616 | |
| 1617 | if opChain.failed() { |