2012-07-16 45 views
7

tôi có các mảng sau:Sorting một loạt các tên các ngày trong tuần

(
    [0] => Array 
     (
      [schedules] => Array 
       (
        [monday] => 1 
        [tuesday] => 1 
        [wednesday] => 1 
        [thursday] => 1 
        [friday] => 1 
        [saturday] => 0 
        [sunday] => 1 
       ) 

     ) 

) 

Tôi muốn sắp xếp các phần tử của mảng này với phím đầu tiên là ngày mai. Giả sử hôm nay là thứ Tư. Tôi muốn mảng của tôi trông như thế này:

(
    [0] => Array 
     (
      [schedules] => Array 
       (
        [thursday] => 1 
        [friday] => 1 
        [saturday] => 0 
        [sunday] => 1 
        [monday] => 1 
        [tuesday] => 1 
        [wednesday] => 1 
       ) 

     ) 
) 

Tôi đã có sẵn các ngày trong tuần (ví dụ: chuỗi 'thứ năm'). Nó được chuyển vào hàm tôi đang làm việc.

Bất kỳ đề xuất nào để đạt được loại sắp xếp này? Cảm ơn!

Trả lời

4

Nếu bạn chuyển đổi ngày thành một số 0-6, bạn có thể array_shiftarray_push nhiều lần để di chuyển các ngày trước đó đến cuối mảng.

+0

bạn có giải pháp đơn giản nhất cho trường hợp của tôi. câu trả lời hay nhất cho bạn nếu bạn có thể cho tôi biết làm thế nào để có được ngày, như một số (0-6) của 'ngày mai hiện tại' – kwikness

+0

Xin lỗi vì trả lời trễ ... 'date ('N')% 7' sẽ làm điều đó cho bạn. N trả về một số 1-7, vì vậy 'ngày ('N')% 7' sẽ là ngày tiếp theo trong số 0-6 của chúng tôi. –

3

Thử sử dụng uksort(). Bạn có thể so sánh ngày tháng trong hàm gọi lại được mô tả trong liên kết.

Ví dụ:

function compare($a, $b) { 
    date(strtotime($a)) - date(strtotime($b)); 
} 

uksort($array, "compare"); 

Dưới đây là proof of it working

+0

Làm cách nào để tính đến giới hạn OP "sắp xếp các phần tử của mảng này bằng khóa đầu tiên là ngày [tuần] [của] ngày mai"? – nickb

+1

Mã tôi sử dụng dưới đây cũng là một uksort, nhưng với một tinh chỉnh nhỏ để phục vụ cho 'sắp xếp từ hôm nay trở đi ...' yêu cầu. – Fluffeh

+0

@Martin, bạn không cần sử dụng 'return' trong hàm' compare'? Ngoài ra, tại sao bạn không thể sử dụng 'strtotime ($ a) - strtotime ($ b)'? – parrker9

1

Trước tiên, bạn cần có một danh sách theo đúng thứ tự mà bạn có thể lấy thông qua các lớp DateTime. Sau đó, khi bạn lặp qua mảng cũ, sử dụng theo đúng thứ tự như chìa khóa để sắp xếp mảng, như vậy:

function sort_by_weekday($input_array) { 
    $now = new DateTime("tomorrow", new DateTimeZone('America/New_York')); 
    $interval = new DateInterval('P1D'); // 1 Day interval 
    $period = new DatePeriod($now, $interval, 7); // 7 Days 

    $sorted_array = array(); 
    foreach($period as $day) { 
     $weekday = strtolower($day->format('l')); 

     foreach($input_array as $key => $value) { 
      $sorted_array[ $key ][ $weekday ] = $value[ $weekday ]; 
     } 
    } 
    return $sorted_array; 
} 

Bạn có thể nhìn thấy nó làm việc trong the demo.

3

Bạn có thể lấy ngày trong tuần qua chức năng date. Chủ nhật là 0, Thứ Hai là 1, v.v.

$weekday = date("w"); 

Sau đó, tôi đề nghị sử dụng uksort chức năng để sắp xếp các mảng liên quan đến phím của nó, trong đó có một chức năng gọi lại như một hướng dẫn phân loại.

uksort($schedules, function ($a, $b) use ($weekday) { 
    // convert each day to a number 0-6 and compare to $weekday 
}); 
0

Tôi đã viết một giải pháp không đưa ngày vào loại ngày/giờ, nhưng thay vào đó sử dụng đóng và uksort. Về cơ bản, mọi khóa được chuyển đến uksort được so sánh với vị trí của khóa "ngày mai", và nếu nó là "trước" ngày mai, nó được "thăng tiến" vào tương lai (+= 7), sau đó kết quả so sánh đơn giản được sử dụng.

sửa để thực hiện: (! Thanks)

Chỉnh sửa thúc đẩy bởi bình luận bằng @nickb

<?php 

function sortedWithNext($days, $tomorrow) { 
    $index_dictionary = array_combine(array_keys($days), range(0,6)); 
    $index_of_tomorrow = $index_dictionary[$tomorrow]; 
    $compare_function = function($k1, $k2) use ($index_dictionary, $index_of_tomorrow) { 
     $index_of_k1 = $index_dictionary[$k1]; 
     $index_of_k2 = $index_dictionary[$k2]; 
     if($index_of_k1 < $index_of_tomorrow) 
      $index_of_k1 += 7; 
     if($index_of_k2 < $index_of_tomorrow) 
      $index_of_k2 += 7; 
     return $index_of_k1 - $index_of_k2; 
    }; 
    uksort($days, $compare_function); 
    return $days; 
} 




$daysPool = array(
'monday'=>1, 
'tuesday'=>1, 
'wednesday'=>1, 
'thursday'=>1, 
'friday'=>0, 
'saturday'=>1, 
'sunday'=>1, 
); 

$tomorrow = 'thursday'; 

$sortedDays = sortedWithNext($daysPool, $tomorrow); 

var_dump($sortedDays); 

hiệu suất ghi nhận

Tôi đã thử nghiệm sử dụng 100.000 lần lặp lại, phương pháp này dành khoảng 2.2e-5 giây để sắp xếp mảng. Người tò mò sẽ kiểm tra phiên bản đầu tiên của câu trả lời này để tìm phiên bản ít hiệu quả hơn, mất khoảng gấp đôi, 5,5e-5 giây.

+1

Vì 'mảng_search' là O (n) và bạn liên tục gọi cả hai' mảng_search' và 'mảng_keys' trong một cuộc gọi lại để sắp xếp, điều này có thể không hiệu quả chút nào. – nickb

+0

Đó là một máy tái cấu trúc khá dễ dàng (khi thuê một trong số chúng ...) –

+0

Và với một máy tái cấu trúc nhỏ khác, tất cả các chức năng nặng đã được loại bỏ khỏi bao đóng; cảm ơn cho các đầu vào, @nickb :-) –

1

Nếu bạn kết hợp một uksort với chức năng đơn giản, đây là giải pháp dễ dàng đáng ngạc nhiên.

Rõ ràng chuyển chuỗi tên ngày thành ints là cần thiết, nhưng nếu ngày trước ngày trong tuần hiện tại, chỉ cần thêm bảy vào biến, điều đó sẽ đảm bảo rằng mảng được sắp xếp là 'sau' ngay cả khi ngày tuần sẽ ngụ ý ngược lại.

<?php 

    $a='sunday'; // Example Input 
    $b='saturday'; // Example Input 

    function funnyDateCompare($a, $b) 
    { 
     $a=date('w',strtotime($a)); 
     $b=date('w',strtotime($b)); 
     if($a<=date('w')) 
     { 
      $a+=7; 
      // First value is less than or equal to today. 
      // Adding 7 to the answer. 
     } 
     return ($a - $b); 
    } 

    uksort($array, "funnyDateCompare") 
?> 
0

này đang làm việc cho tôi, chỉ cần một vòng lặp đơn giản:

$array = array(); 

$month = date('m'); 
$day = date('d'); 
$year = date('Y'); 

for($i=1; $i<=7; $i++){ 
    $array[] = date('l',mktime(0,0,0,$month,($day+$i),$year)); 
} 

mảng Output trông giống như: (Nếu hôm nay là một thứ ba)

array(
    (int) 0 => 'Wednesday', 
    (int) 1 => 'Thursday', 
    (int) 2 => 'Friday', 
    (int) 3 => 'Saturday', 
    (int) 4 => 'Sunday', 
    (int) 5 => 'Monday', 
    (int) 6 => 'Tuesday' 
) 
0

trả lời này cho phép mà Day of Tuần bắt đầu tại và tự động xử lý các ngày được gắn nhãn.

Đây chỉ là giải pháp được cải tiến sử dụng uksort(), date()strtotime().

function sort_days($term1, $term2) { 
    $weekdays = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'); 
    foreach ($weekdays as $key => $value) { 
     $weekdays[ $key ] = date('N', strtotime($value)); 
    } 

    $term1_time = date('N', strtotime(strtolower($term1))); 
    $term2_time = date('N', strtotime(strtolower($term2))); 

    return array_search($term1_time, $weekdays) - array_search($term2_time, $weekdays); 
} 

Sorting phím với uksort()

$uk_days = array(
    'thursday' => 1, 
    'monday' => 1, 
    'saturday' => 1, 
    'wednesday' => 1, 
    'sunday' => 1, 
    'friday' => 1, 
    'tuesday' => 1, 
); 
uksort($uk_days, "sort_days"); 
var_dump($uk_days); 

phím Sorting với usort()

$u_days = array(
    'thursday', 
    'monday', 
    'saturday', 
    'wednesday', 
    'sunday', 
    'friday', 
    'tuesday', 
); 
usort($u_days, "sort_days"); 
var_dump($u_days); 
Các vấn đề liên quan