skip to Main Content

I have a sorted array is

array = [
    { id: 1, orderTotal: 50000 },
    { id: 3, orderTotal: 50000 },
    { id: 2, orderTotal: 100000 },
    { id: 4, orderTotal: 200000 },
] 

I want find all order total if nearest with a total price.

This is my code

const getNearestOrderValue = (arr, totalPrice) => {
    let nearestItem = [];
    let maxSmaller = 0;
    
    for (const item of arr) {
        if (item?.orderTotal <= totalPrice && item?.orderTotal >= maxSmaller) {
          maxSmaller = item?.orderTotal;
          nearestItem.push(item);
        }
    }
    return nearestItem;
}

if total price = 80000, my code return correct result is

[
   { id: 1, orderTotal: 50000 },
   { id: 3, orderTotal: 50000 },
]

but if total price is 120000, my code result is

[
  { id: 1, orderTotal: 50000 },
  { id: 3, orderTotal: 50000 },
  { id: 2, orderTotal: 100000 }
]

I want result is

[
 { id: 2, orderTotal: 100000 }
]

How can i fix this getNearestOrderValue function to response correct? I am looking forward to receive help from anyone.

4

Answers


  1. You can loop twice. Once to find the maxSmaller item and then to filter the original array:

    /*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/ 
    const getNearestOrderValue = (arr, totalPrice) => {
      let maxSmaller = 0;
      for (const item of arr) {
        if (item?.orderTotal <= totalPrice && item?.orderTotal >= maxSmaller) {
          maxSmaller = item?.orderTotal;
        }
      }
      return arr.filter((item) => item?.orderTotal === maxSmaller);
    };
    console.log(
      getNearestOrderValue(
        [
          { id: 1, orderTotal: 50000 },
          { id: 3, orderTotal: 50000 },
          { id: 2, orderTotal: 100000 },
          { id: 4, orderTotal: 200000 },
        ],
        120000
      )
    );
    <!-- https://meta.stackoverflow.com/a/375985/ -->    <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
    Login or Signup to reply.
  2. You just have to reset your output array when you find a closer value. There is no need to loop 2*n times and definitely no need to loop n^2 times.

    const array = [
        { id: 1, orderTotal: 50000 },
        { id: 3, orderTotal: 50000 },
        { id: 2, orderTotal: 100000 },
        { id: 4, orderTotal: 200000 },
    ];
    
    const getNearestOrderValue = (arr, totalPrice) => {
        let nearestItem = [];
        let maxSmaller = 0;
        
        for (const item of arr) {
            if (item?.orderTotal > totalPrice) {
              break;
            } else if (item?.orderTotal >= maxSmaller) {
              if (item?.orderTotal > maxSmaller) {
                maxSmaller = item?.orderTotal;
                nearestItem = [];
              }
              nearestItem.push(item);
            }
        }
        return nearestItem;
    }
    
    console.log(getNearestOrderValue(array, 50000));
    console.log(getNearestOrderValue(array, 120000));

    As noted by Nick Parsons in the comments, you can even break out of the loop once you encounter an orderTotal that is greater than the totalPrice.

    Login or Signup to reply.
  3. You could reduce the array and keep only items with smaller total values.

    const
        findNearest = (data, total) => data
            .reduce((r, o, i, a) => {
                if (o.orderTotal > total) return r;
                if (r.at(-1)?.orderTotal < o.orderTotal) r = [];
                r.push(o);
                return r;
            }, []),
        array = [{ id: 1, orderTotal: 50000 }, { id: 3, orderTotal: 50000 }, { id: 2, orderTotal: 100000 }, { id: 4, orderTotal: 200000 }];
    
    console.log(findNearest(array, 80000));
    console.log(findNearest(array, 120000));
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  4. const array = [
        { id: 1, orderTotal: 50000 },
        { id: 3, orderTotal: 50000 },
        { id: 2, orderTotal: 100000 },
        { id: 4, orderTotal: 200000 },
    ];
    
    // Target order total
    const targetTotal = 80000;
    
    // Find the item with the order total closest to the target total
    const nearestItem = array.reduce((closest, current) => {
        const closestDifference = Math.abs(targetTotal - closest.orderTotal);
        const currentDifference = Math.abs(targetTotal - current.orderTotal);
    
        return currentDifference < closestDifference ? current : closest;
    });
    
    console.log('nearestItem',nearestItem);

    Check this out it will resolve your problem.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search