9

私は次の配列を持っています:

[
     [
         'schedules' => [
             'monday' => 1,
             'tuesday' => 1,
             'wednesday' => 1,
             'thursday' => 1,
             'friday' => 1,
             'saturday' => 0,
             'sunday' => 1,
         ]
    ]
]

この配列の要素を回転させて、最初のキーを明日にします。今日が水曜日だったとしましょう。アレイを次のようにしたいと思います。

[
     [
         'schedules' => [
             'thursday' => 1,
             'friday' => 1,
             'saturday' => 0,
             'sunday' => 1,
             'monday' => 1,
             'tuesday' => 1,
             'wednesday' => 1,
         ]
    ]
]

私はすでに平日を利用できます(たとえば、文字列「木曜日」)。それは私が使っている関数に渡されます。

4

12 に答える 12

5

日を0〜6の数値に変換すると、その日をarray_shiftarray_push度も変換して、前の日を配列の最後に移動できます。

于 2012-07-16T02:24:24.227 に答える
3

を使用してみてくださいuksort()。リンクで説明されているコールバック関数で日付を比較できます。

例えば:

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

uksort($array, "compare"); 

これが機能している証拠です

于 2012-07-16T02:25:55.793 に答える
2

日付関数を使用して曜日を取得できます。日曜日は0、月曜日は1などです。

$weekday = date("w");

次に、uksort関数を使用して、キーを基準にして配列を並べ替えることをお勧めします。これは、並べ替えのガイドラインとしてコールバック関数を使用します。

uksort($schedules, function ($a, $b) use ($weekday) {
    // convert each day to a number 0-6 and compare to $weekday
});
于 2012-07-16T02:32:16.590 に答える
2

あなたはこれを達成するためにこのようにすることができます

$week = [
    'sunday',
    'monday',
    'tuesday',
    'wednesday',
    'thursday',
    'friday',
    'saturday',
];

  $day = date('w'); // weekday as integer(3 for Wednesday)

  for ($i=0; $i <= $day ; $i++) {
    array_push($week, array_shift($week));
  }

  $result = $week;

結果(今日が水曜日の場合):

    Array
    (
        [0] => thursday
        [1] => friday
        [2] => saturday
        [3] => sunday
        [4] => monday
        [5] => tuesday
        [6] => wednesday
    )
于 2018-07-04T08:02:09.907 に答える
1

uksortと単純な関数を組み合わせると、これは驚くほど簡単なソリューションです。

明らかに、曜日名の文字列をintに変換する必要がありますが、曜日が現在の平日より前の場合は、変数に7を追加するだけで、曜日が意味する場合でも、配列が「後」としてソートされることが保証されます。そうでなければ。

<?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")
?>
于 2012-07-16T03:46:30.530 に答える
1

まず、正しい順序のリストが必要です。これは、DateTimeクラスから取得できます。次に、古い配列をループするときに、次のように、配列を並べ替えるキーとして正しい順序を使用します。

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;
}

あなたはそれがデモで働いているのを見ることができます。

于 2012-07-16T02:26:51.180 に答える
1

この回答では、どの曜日から開始するかを指定し、曜日のラベル付け方法を動的に処理します。

これは、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 );
}

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);

usort()を使用したキーの並べ替え

$u_days = array(
    'thursday',
    'monday',
    'saturday',
    'wednesday',
    'sunday',
    'friday',
    'tuesday',
);
usort($u_days, "sort_days");
var_dump($u_days);
于 2017-04-05T03:22:04.670 に答える
0

日を日付/時刻タイプにキャストせず、代わりにクロージャーとuksortを使用するソリューションを作成しました。基本的に、uksortに渡されたすべてのキーは「明日」キーの位置と比較され、明日が「前」の場合は将来に「昇格」され(+= 7)、単純な比較結果が使用されます。

パフォーマンスのために編集:

@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);

パフォーマンスノート

100,000回の反復を使用してテストしましたが、このメソッドは配列の並べ替えに約2.2e-5秒かかります。好奇心旺盛な人は、この回答の最初のバージョンをチェックして、約2倍の5.5e-5秒かかったパフォーマンスの低いバージョンを見つけます。

于 2012-07-16T02:40:23.127 に答える
0

以下のコードを試してください。現在の日に基づいて日を並べ替えます。

    $days = array("Friday","Thursday","Wednesday","Tuesday");
    $days = array_combine($days,$days);
    
    //loop the days and check the next day
    foreach($days as $k => $dd){
        
        //check next day name & increment current date with +1
        $current_dt = date("Y-m-d",strtotime("next day", strtotime($current_dt)));
        $days_name = date("l", strtotime($current_dt));    
        
        // if day name exists in array, push in seperate array
        if(!empty($days[$days_name])){
            $arrSortedDays[] = $days_name;
        }
    }
    
    //check if currnet day fall today, push it in array to last element.
    if(!empty($days[date("l")])){
        $arrSortedDays[] = date("l");
    } 
于 2020-08-24T13:45:48.140 に答える
0

サブアレイデータにはすでに循環順序があるため、各エントリを相互に比較して並べ替える必要はありません。

(私が知っている)最も直接的な解決策は次のとおりです。

  1. アレイを2つの部分に切断する正しい位置を見つけてから、
  2. 最初のパーツを取り外し、2番目のパーツの後に再度取り付けます。

コード:(デモ

$newStart = 'thursday';
foreach ($array as &$entry) {
    $position = array_search(
        $newStart,
        array_keys($entry['schedules'])
    );
    if ($position) {
        $entry['schedules'] += array_splice(
            $entry['schedules'],
            0,
            $position
        );
    }
}
var_export($array);

この条件は、ターゲットキーが見つからない場合(false)またはすでに最初の位置にある場合(0)に要素の回転が実行されないことを保証します。

array_search()最初の一致が見つかるとすぐに反復を停止するため、効率的です。

私は、以下を推奨する以前の回答のいずれも支持しません。

  • uksort()-これは、カスタム関数本体での関数呼び出しの追加のオーバーヘッドは言うまでもなく、計算の複雑さを増します。
  • ループ-繰り返される関数呼び出しは不必要に高価であり、あまりエレガントではない/力ずくのテクニックを表しています。ブレーク条件があり、関数呼び出しが繰り返されないループはそれほど悪くはありません。
  • OPの入力データを別のソリューションにより適したものに変更する-これは不必要に敗北を認めています。

私のソリューションは、日付関連のデータ/ロジックに依存しないため、たまたま効用関数として適しています。

于 2021-05-28T13:35:24.393 に答える
0

との組み合わせでうまくarray_sliceいきarray_mergeます。

'week' => [
   'monday' => 1,
   'tuesday' => 1,
   'wednesday' => 1,
   'thursday' => 1,
   'friday' => 1,
   'saturday' => 0,
   'sunday' => 1,
         ]
// get today's index, like Wednesday will be 3
$day = date('w')

// Get the days until today
$previous = array_slice($week, 0, $day); // ["mon","tue","wed"]

// Get remaining days in week
$coming = array_slice($week, $day); //  ["thu","fri","sat","sun",]

array_merge($coming, $previous);//["thu","fri","sat","sun","mon","tue","wed"]
于 2022-02-14T14:24:51.333 に答える
-1

これは私のために働いています、ただの単純なループ:

$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));
}

出力配列は次のようになります:(今日が火曜日の場合)

array(
    (int) 0 => 'Wednesday',
    (int) 1 => 'Thursday',
    (int) 2 => 'Friday',
    (int) 3 => 'Saturday',
    (int) 4 => 'Sunday',
    (int) 5 => 'Monday',
    (int) 6 => 'Tuesday'
)
于 2014-05-27T10:30:16.437 に答える