0

Consider the following array $arr_sessions:

[
  {
    "url": "2019_7_5_0_52_RACE.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_5_0_27_RACE.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_5_0_16_QUALIFY.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_5_0_0_PRACTICE.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_4_23_9_RACE.json",
    "trackName": "ttassen"
  },
  {
    "url": "2019_7_4_23_52_RACE.json",
    "trackName": "ttassen"
  },
  {
    "url": "2019_7_2_11_25_RACE.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_2_11_03_RACE.json",
    "trackName": "road-america"
  }
]

Based upon this array I'd like to create a new $arr_results as follows:

[
  {
    "url": [
      "2019_7_5_0_52_RACE.json",
      "2019_7_5_0_27_RACE.json",
      "2019_7_5_0_16_QUALIFY.json",
      "2019_7_5_0_0_PRACTICE.json"
    ],
    "trackName": "road-america"
  },
  {
    "url": [
      "2019_7_4_23_9_RACE.json",
      "2019_7_4_23_52_RACE.json"
    ],
    "trackName": "ttassen"
  },
  {
    "url": [
      "2019_7_2_11_25_RACE.json",
      "2019_7_2_11_03_RACE.json"
    ],
    "trackName": "road-america"
  }
]

As you can see, the requirements here are to combine the values for 'url' for as long as 'trackName' stays the same as the next one, however don't group them if the same 'trackName' should exist somewhere else (like in this example we have 2 times "road-america", however these shouldn't get combined since there is a different 'trackName' in between).

So far I spend significant time trying to figure it out how to get there (I guess this has to be done with nested loops?)

Update

Here's 1 of the things I tried (but clearly this only looks at the next 'trackName' - not sure how to continue from here)

for ($s = 0; $s < count($arr_sessions); $s++) {

    $n= $s+1;

    if($arr_sessions[$n]["trackName"] == $arr_sessions[$s]["trackName"]){
        $arr_results[$s]['name'] = $arr_sessions[$s]["sessionName"];
        $arr_results[$s]['log'] = array($arr_sessions[$s]["url"], $arr_sessions[$n]["url"]);
        $s += 1;
    }

}

4
  • 2
    Did you try looping the array? Commented Jul 7, 2019 at 9:01
  • @Andreas Yes, I did but I failed to understand how to do it correctly. Thanks Commented Jul 7, 2019 at 9:04
  • Show what you tried, then we'll show you how to fix it. We're not going to write it for you from scratch. Commented Jul 7, 2019 at 9:05
  • It should just be a matter of setting a variable to the last trackName. Then you check if $current['trackName'] == $prev_trackname. If it is, you add to the current element of the result, otherwise you start a new element. Commented Jul 7, 2019 at 9:06

4 Answers 4

2

Don't look at the next trackname, save the trackname from the previous iteration in a variable. Whenever it changes, you start a new element in the results array.

$arr_results = [];
$prev_trackname = null;
$i = -1;
foreach ($arr_sessions as $current) {
    if ($current['trackName'] != $prev_trackname) {
        $i++;
        $arr_results[$i] = ['trackName' => $current['trackName'], 'url' => []];
        $prev_trackname = $current['trackName'];
    }
    $arr_results[$i]['url'][] = $current['url'];
}
Sign up to request clarification or add additional context in comments.

3 Comments

you're awesome!! Thanks a lot! (now let me study what you did here). Thanks again!
I wondered, this is not gonna work because it's gonna renew url property each time in line 8.
Assigning to $arr_results[$i]['url'][] means to push onto the array, not replace it.
1

Here is a complete example with output. You need to check if the track name is the same as the previous one, and build your array accordingly.

$a = json_decode('[
  {
    "url": "2019_7_5_0_52_RACE.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_5_0_27_RACE.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_5_0_16_QUALIFY.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_5_0_0_PRACTICE.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_4_23_9_RACE.json",
    "trackName": "ttassen"
  },
  {
    "url": "2019_7_4_23_52_RACE.json",
    "trackName": "ttassen"
  },
  {
    "url": "2019_7_2_11_25_RACE.json",
    "trackName": "road-america"
  },
  {
    "url": "2019_7_2_11_03_RACE.json",
    "trackName": "road-america"
  }
]');

// Set previous track to null
$prev_track = NULL;
// New array
$new_a = [];
// Set counter
$i = 0;

foreach ($a as $value) {

  // If previous track name is different than current track name
  if ($prev_track !== $value->trackName) {

    // Increment counter
    $i++;
    // Create a new array entry
    $new_a[$i] = ['trackName' => $value->trackName, 'url' => [$value->url]];

  } else {
    // Append to previously created array entry
    $new_a[$i]['url'][] = $value->url;
  }

  // Set previous track to current track
  $prev_track = $value->trackName;
}

print json_encode(array_values($new_a));

This will output:

[
  {
    "trackName": "road-america",
    "url": [
      "2019_7_5_0_52_RACE.json",
      "2019_7_5_0_27_RACE.json",
      "2019_7_5_0_16_QUALIFY.json",
      "2019_7_5_0_0_PRACTICE.json"
    ]
  },
  {
    "trackName": "ttassen",
    "url": [
      "2019_7_4_23_9_RACE.json",
      "2019_7_4_23_52_RACE.json"
    ]
  },
  {
    "trackName": "road-america",
    "url": [
      "2019_7_2_11_25_RACE.json",
      "2019_7_2_11_03_RACE.json"
    ]
  }
]

Comments

0

Assuming that $arr_sessions is actually JSON you can try following code:

$output = [];
$data = json_decode($input);

foreach($data as $key=>$value) {
    if(isset($output[$value->trackName])) {
        array_push($output[$value->trackName]['url'], $value->url);
    } else {
        $output[$value->trackName] = [
            'trackName' => $value->trackName,
            'url' => [$value->url]
        ];
    }
}
$your_desired_format = array_values($output);

5 Comments

a valid point, however my array is already decoded from an existing JSON, and I'm writing a new JSON file based upon this new array. Thanks!
Won't this group all with the same track name? That is not what OP requested
@Andreas no, if trackName exist in associative array just url will be added, otherwise new key (trackName) will be created.
No, see 3v4l.org/jZmSc you mix all track names in one subarray see OPs request. There should be three subarrays not two
@Andreas I see, I grouped it generally and OP wanted group for every track Name which are in a row. Anyway that variant can be useful as well). Thanks for correction.
0

Check this out:

$lastKey = '';
$index = 0;
$arr = [];
foreach ($arr_sessions as $record) {
  $trackName = $record->trackName;
  if ($lastKey !== $trackName) {
    $lastKey = $trackName;
    $index++;
  }
  if (!$arr[$index]) {
    $arr[$index] = (object) [
      'trackName' => $lastKey,
      'url' => []
    ];  
  }
  array_push($arr[$index]->url, $record->url);
}
$arr = array_values($arr);
print_r($arr);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.