두 개의 데이터 세트를 하나로 결합

얼마 전 둥근 구멍에 네모난 못을 추가해 달라는 고객 요청이 있었습니다. 매우 다른 두 개체를 단일 컬렉션으로 반환해야 했습니다. 물론 이것은 이 업계에서 항상 발생합니다. 그리고 두 개체의 좋은 부분을 하나의 결합된 단위로 나타낼 수 있는 새 개체를 추가하는 것은 분명히 큰 문제가 아닙니다.

그러나 결과적으로 더 흥미로운 문제 중 하나는 다음과 같은 검색 방법이 필요하다는 것입니다.
  • 서로 다른 두 데이터 세트에서 객체를 확실히 반환함
  • 여전히 클라이언트 응용 프로그램의 전체take 리미터를 적용합니다.

  • 즉, 클라이언트 앱이 10개의 레코드만 요청하지만 두 데이터 세트 중 일부가 있는 경우 두 데이터 세트 중 일부(가능한 경우)가 확실히 존재하면서 전체 반환이 요청된 위치에서 중지되도록 최종 결과를 어떻게 제한합니까? 한계?

    첫 번째 데이터 세트에는 결과가 없고 다른 데이터 세트에는 결과가 있는 경우 분명히 요청된 테이크 수를 사용할 수 있습니다.

    하지만 둘 다에 몇 개가 있을 때, 특히 하나에는 무리가 있고 다른 하나에는 한두 개만 있을 때 까다로워집니다.

    클라이언트 앱이 10개의 레코드를 요청했고, 하나의 데이터세트는 9개를 반환하고 다른 하나는 1개를 반환한다고 가정해 보겠습니다. 둘 다 가져갈 수 있습니다. 10보다 적습니다. 모두 좋습니다. 그러나 하나가 6개이고 다른 하나가 42개라면 어떻게 될까요? 아니면 둘 다 수천?

    AI를 사용하거나 더 영리한 다른 방법을 사용하여 수학적으로 이를 처리하는 보다 정교한 방법이 있을 것이라고 확신합니다. 그러나 이것이 내가 생각해 낸 것입니다.

    👇 Run this in dotnetfiddle

    public static (int leftTakeCount, int rightTakeCount) GetTakeCountsFromTwoSourcesToMeetOneTotalQuota(int take, int leftCount, int rightCount)
    {
        int halfTake = take / 2; // since it's an int here, the decimal will just truncate
        int totalCount = leftCount + rightCount;
    
        bool totalCountAboveTake = totalCount > take;
    
        bool leftAboveHalfTake = leftCount > halfTake;
        bool shouldReduceLeft = totalCountAboveTake && leftAboveHalfTake;
    
        bool rightAboveHalfTake = rightCount > halfTake;
        bool shouldReduceRight = totalCountAboveTake && rightAboveHalfTake;
    
        // When both counts are above the requested take count and also above the halfTake, then we can just chop both down to the half count
        bool canReduceBothToHalftake = totalCountAboveTake & leftAboveHalfTake & rightAboveHalfTake;
        int leftReductionToHalfTake = canReduceBothToHalftake ? leftCount - halfTake : 0;
        int rightReductionToHalfTake = canReduceBothToHalftake ? rightCount - halfTake : 0;
    
        // When one of the counts is below halfTake, we need to calculate the difference so that we'll end up with some of both
        int leftReductionToDifference = (shouldReduceLeft & !canReduceBothToHalftake) ? leftCount - (take - rightCount) : 0;
        int rightReductionToDifference = (shouldReduceRight & !canReduceBothToHalftake) ? rightCount - (take - leftCount) : 0;
    
        // Since we used booleans above, one of these will end up as 0. So get the other one
        int maxLeftReduction = Math.Max(leftReductionToHalfTake, leftReductionToDifference);
        int maxRightReduction = Math.Max(rightReductionToHalfTake, rightReductionToDifference);
    
        int finalLeftReduction = shouldReduceLeft ? maxLeftReduction : 0;
        int finalRightReduction = shouldReduceRight ? maxRightReduction : 0;
    
        int leftTakeCount = leftCount - finalLeftReduction;
        int rightTakeCount = rightCount - finalRightReduction;
    
        return (leftTakeCount, rightTakeCount);
    }
    


    여기서는 두 카운트의 합이 요청된 금액take보다 작거나 같으면 둘 다 사용할 수 있다고 가정합니다. 그러나 합계가 그보다 크면 더 작은 쪽을 위한 공간을 남겨두기 위해 더 큰 쪽을 지능적으로 줄여야 합니다. 그리고 두 집합 모두에 묶음이 있는 경우 요청된 값take을 반으로 자르고 두 값 중 그만큼을 반환할 수 있습니다.

    결과는 두 번째 또는 '오른쪽' 데이터 세트와 별도로 첫 번째 또는 '왼쪽' 데이터 세트의 값take을 제공하는 튜플입니다. 이를 통해 두 세트에 대한 데이터베이스 쿼리를 제한할 수 있으므로 클라이언트가 요청한 총 레코드 수가 무엇이든 됩니다.

    여기서 다룰 시간이 없는 한 가지 분명한 문제는 inthalfTake 값으로 사용하고 있으므로 나머지 십진수 값을 처리하기 때문에 25와 같은 짝수를 요청하면 halfTake 는 가장 가까운 int 로 반올림되고 하나의 추가 레코드가 생깁니다.

    하지만 클라이언트 앱을 제어하기 때문에 . . . 나는 그렇게 하지 않을 것이고 지금은 그것에 대해 걱정하지 않을 것입니다. 게다가 내 소비 서비스 메서드는 실제로 이러한 값을 나중에 정렬해야 하므로 클라이언트에 반환하기 전에 서비스에서 다른.Take(request.Take) 문으로 추가 항목을 잘라낼 수 있습니다.

    좋은 웹페이지 즐겨찾기