簡體   English   中英

根據聚合嵌套值對 JSON 和 PHP 進行排序

[英]Sort JSON with PHP based on aggregated nested values

我需要:

  1. 每個組合總價對 arrays 進行排序。
  2. 只返回其中總價最高的 40%。
$combinations = '[
    [                          //1st combination
        {"id":1,"price":11900},
        {"id":2,"price":499},
        {"id":3,"price":2099}
    ],
    [                          //2nd combination
        {"id":1,"price":11900},
        {"id":2,"price":499},
        {"id":4,"price":999}
    ],
    [                          //3rd combination
        {"id":1,"price":11900},
        {"id":2,"price":499},
        {"id":5,"price":899}
    ],
    [                          //4th combination
        {"id":1,"price":11900},
        {"id":2,"price":499},
        {"id":6,"price":2999}
    ]
]';
<?php

$json = json_decode('[
    [{"id":1,"price":11900},{"id":2,"price":499},{"id":3,"price":2099}],
    [{"id":1,"price":11900},{"id":2,"price":499},{"id":4,"price":999}],
    [{"id":1,"price":11900},{"id":2,"price":499},{"id":5,"price":899}],
    [{"id":1,"price":11900},{"id":2,"price":499},{"id":6,"price":2999}]
    ]');

// var_dump($json);

// ($a, $b) for ASC sorting
// ($b, $a) for DESC sorting
usort($json, function ($b, $a) {

    $a_prices = 0;
    foreach($a as $aa)
        $a_prices += $aa->price;

    $b_prices = 0;
    foreach($b as $bb)
        $b_prices += $bb->price;

    return $a_prices - $b_prices;
});

// Find where 40% stops
// It is up to you to choose between round(), ceil() or floor()
$breakpoint = round(sizeof($json) * 40 / 100);

$sorted_chunk = array_slice($json, 0, $breakpoint);
var_dump($sorted_chunk);

雖然@medilies 的回答簡單而正確,但這里有一種更經濟的數據排序方法。 如果我們正在處理一個大型數據集,那么直接的usort可能會變得相當昂貴——因為必須為每個$a$b比較重新計算比較值。 相反,我們可以預先計算總和並使用“緩存”值進行比較。

// Here's the data; decoded as an array:

$json = json_decode('[
    [{"id":1,"price":11900},{"id":2,"price":499},{"id":3,"price":2099}],
    [{"id":1,"price":11900},{"id":2,"price":499},{"id":4,"price":999}],
    [{"id":1,"price":11900},{"id":2,"price":499},{"id":5,"price":899}],
    [{"id":1,"price":11900},{"id":2,"price":499},{"id":6,"price":2999}]
    ]', true);
    
// Calculate the sums for all prices per row up-front.
// Map array into sums: Get the sum for each row's "price" columns

$sums = array_map(fn($v) => array_sum(array_column($v, 'price')), $json);

// Use $sums in our key-based sorter for the comparison values:

uksort($json, function($b, $a) use ($sums) {
    return $sums[$a] <=> $sums[$b];
});

// See the sums, get the sorted data:

var_dump($sums, $json);

這里我們使用uksort而不是usort ,因為我們只需要知道正在排序的數組成員的 我們的“比較緩存”或$sums數組,鍵與目標數組匹配,通過use()傳遞到排序 function。在 function 中,我們簡單地比較$sums[$a]$sums[$b]中的匹配值$sums[$b] ,不重復求和計算。 演示: https://3v4l.org/sNluJ#v8.1.3

在這種情況下,需要大量數據集才能產生顯着差異。 如果需要更昂貴的迭代(例如,多次“繁重的”function 調用)才能獲得要比較的值,則“預先且僅一次”評估將節省大量不必要的計算周期。

在返回 OP 想要的最終前 40% 結果時,請參考已接受的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM