When I try to push an array of records to my Laravel Collection, I end up with only the first record being inserted into the collection. It was working well before I made a few changes (related to $limit and $test) but now produces this bug.
public static function processOldOrders(int $limit = 1, bool $test = true)
{
//Read CSV and turn into a collection
$allOldOrders = Excel::toArray([], 'orders.csv');
$orderCollection = collect();
$count = 0;
foreach ($allOldOrders as $key => $oldOrder) {
$orderCollection->push(
(object) [
'order_id' => ltrim($oldOrder[$key][0], "#"),
'order_created' => $oldOrder[$key][4],
'email' => $test ? 'test#test.com' : trim(strtolower($oldOrder[$key][5])),
'phone' => ltrim($oldOrder[$key][12], "'"),
'first_name' => $oldOrder[$key][7],
'last_name' => $oldOrder[$key][8],
'purchase_status' => 'a_purchase',
'total_price' => $oldOrder[$key][33],
'items' => [],
'gift_cards' => [],
'coupons' => [],
'shipping_data' => [],
]
);
$count++;
if ($count >= $limit) {
break;
}
}
dd($orderCollection);
In your processOldOrders method by default you set limit = 1. And on the bottom,
$count = 0;
foreach ($allOldOrders as $key => $oldOrder) {
...
$count++;
if ($count >= $limit) {
break;
}
...
there you check it with count. At first time $count is equal to 0, and you plus it 1. Then you checking it with $limit. By default limit is 1 . So it works only one time. Yu have to more than one limit where you call processOldOrders method
There's nothing wrong with your code. But you forgot the output of Excel::toArray(), that it has sub-arrays.
array:1 [
0 => array [ // <-- init
0 => array [ // <-- CSV data
...
So, you can change your $allOldOrders to $allOldOrders[0] :
foreach ($allOldOrders[0] as $key => $oldOrder) {
...
}
Related
I have a already defined array, containing values just like the one below:
$arr = ['a','b','c'];
How could one add the following using PHP?
$arr = [
'a' => 10,
'b' => 5,
'c' => 21
]
I have tried:
$arr['a'] = 10 but it throws the error: Undefined index: a
I am surely that I do a stupid mistake.. could someone open my eyes?
Full code below:
$finishes = []; //define array to hold finish types
foreach ($projectstages as $stage) {
if ($stage->finish_type) {
if(!in_array($stage->finish_type, $finishes)){
array_push($finishes, $stage->finish_type);
}
}
}
foreach ($projectunits as $unit) {
$data[$i] = [
'id' => $unit->id,
'project_name' => $unit->project_name,
'block_title' => $unit->block_title,
'unit' => $unit->unit,
'core' => $unit->core,
'floor' => $unit->floor,
'unit_type' => $unit->unit_type,
'tenure_type' => $unit->tenure_type,
'floors' => $unit->unit_floors,
'weelchair' => $unit->weelchair,
'dual_aspect' => $unit->dual_aspect
];
$st = array();
$bs = '';
foreach ($projectstages as $stage) {
$projectmeasure = ProjectMeasure::select('measure')
->where('project_id',$this->projectId)
->where('build_stage_id', $stage->id)
->where('unit_id', $unit->id)
->where('block_id', $unit->block_id)
->where('build_stage_type_id', $stage->build_stage_type_id)
->first();
$st += [
'BST-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure : '0')
];
if (($stage->is_square_meter == 0) && ($stage->is_draft == 0)) {
$height = ($stage->height_override == 0 ? $unit->gross_floor_height : $stage->height_override); //08.14.20: override default height if build stage type has it's own custom height
$st += [
'BST-sqm-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure * $height: '0')
];
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure * $height: '0') * ($stage->both_side ? 2 : 1); //error is thrown at this line
}
} else {
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure : '0');
}
}
}
$data[$i] = array_merge($data[$i], $st);
$data[$i] = array_merge($data[$i], $finishes[$stage->finish_type]);
$i++;
}
The above code is used as is and the array $finishes is the one from the first example, called $arr
You're using += in your real code instead of =. That tries to do maths to add to an existing value, whereas = can just assign a new index with that value if it doesn't exist.
+= can't do maths to add a number to nothing. You need to check first if the index exists yet. If it doesn't exist, then assign it with an initial value. If it already exists with a value, then you can add the new value to the existing value.
If you want to convert the array of strings to a collection of keys (elements) and values (integers), you can try the following:
$arr = ['a','b','c'];
$newVals = [10, 5, 21];
function convertArr($arr, $newVals){
if(count($arr) == count($newVals)){
$len = count($arr);
for($i = 0; $i < $len; $i++){
$temp = $arr[$i];
$arr[$temp] = $newVals[$i];
unset($arr[$i]);
}
}
return $arr;
}
print_r(convertArr($arr, $newVals));
Output:
Array ( [a] => 10 [b] => 5 [c] => 21 )
how I can sort this by number, 0 - 1+ not by first letter?
error_reporting(E_ALL);
ini_set("display_errors", 1);
$players = array();
$playerIds = [
'76561197972192473',
'76561198972352439',
'76561198087304080',
'76561198799985528',
'76561198338485290'
];
$url = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=294CFDFSFCWE5EG5FE4&steamids=".implode(',', $playerIds);
$json_object= file_get_contents($url);
$json_decoded = json_decode($json_object);
foreach ($json_decoded->response->players as $key=>$player) {
$players[] = [
'name' => $player->personaname,
'profileurl' => $player->profileurl,
'avatarfull' => $player->avatarfull,
'personastate' => $player->personastate
];
}
usort($players, function($a, $b) {
if ($a['name'] === $b['name']) {
return 0;
}
return ($a['name'] < $b['name']) ? -1 : 1;
});
When I remove usort, steam api will return ids everytime in different order, so can you help me how I can make it starts with 0 from playerIds.
Just add the steamid as the index and then sort it on keys:
foreach ($json_decoded->response->players as $key=>$player) {
$players[$player->steamid] = [
'name' => $player->personaname,
'profileurl' => $player->profileurl,
'avatarfull' => $player->avatarfull,
'personastate' => $player->personastate
];
}
ksort($players);
Alternately, you could do it the way you're doing it but add the steamid to the $players array:
$players[] = [
'id' => $player->steamid,
'name' => $player->personaname,
'profileurl' => $player->profileurl,
'avatarfull' => $player->avatarfull,
'personastate' => $player->personastate
];
Then sort on the id:
array_multisort(array_column($players, 'id'), SORT_DESC, $players);
There is maybe a parameter to be passed to the API that will return them sorted the way you want, not sure.
I have two arrays which are populated from two separate api requests.
protected $playerDetails = ['name' => [], 'role' => [], 'donations' => [], 'donationsReceived' => [], 'lastSeen' => []];
protected $warDetails = ['name' => [], 'warCollectionBattles' => [], 'warCardsEarned' => [], 'allocatedFinalBattles' => [], 'numberOfFinalBattlesPlayed' => [], 'warFinalBattleWin' => []];
Originally I had these 2 separate arrays as the data returned from both api requests has different indexes but as they share a common value name I am trying to refactor both arrays into one array.
protected $playerDetails = ['name' => [], 'role' => [], 'donations' => [], 'donationsReceived' => [], 'lastSeen' => [], 'warCollectionBattles' => [], 'warCardsEarned' => [], 'allocatedFinalBattles' => [], 'numberOfFinalBattlesPlayed' => [], 'warFinalBattleWin' => []];
So far I have the following code, which is working up until I try to assign $this->playerDetails['warFinalBattleWin'] but I am uncertain to why this isn't assigning like any other variable would be assigned.
//gets the index of the playerDetails aray
for ($i = 0; $i <= count($this->playerDetails); $i++) {
//gets the index of the data from the api response
for ($x=0; $x <= count($warArr['participants'])-1 ; $x++){
//this outputs the name and wins as expected
echo $warArr['participants'][$x]['name'] ;
echo $warArr['participants'][$x]['wins'] . "<BR>";
//checks that the name from the playerDetails array matches the name from the api response at each index
if($this->playerDetails['name'][$i] == $warArr['participants'][$x]['name']){
$this->playerDetails['warFinalBattleWin'][$i] = $warArr['participants'][$x]['wins'];
}
}
break;
}
//this outputs an empty array
print_r($this->playerDetails['warFinalBattleWin']);
Also would someone be able to explain why on this line
for ($x=0; $x <= count($warArr['participants'])-1 ; $x++){
I have to subtract 1 from the count of the array? If I don't do this I get an undefined offset notice such as
Undefined offset: (value of count($warArr['participants']) )
In the first for loop where I was getting the index for each player from the playerDetails array I was getting the count of the first dimension of this array when I should have been using count on $this->playerDetails['name'] and then removing the break
So the working code looks like this
for ($i = 0; $i < count($this->playerDetails['name']); $i++) {
for ($x=0; $x < count($warArr['participants']) ; $x++){
if($this->playerDetails['name'][$i] == $warArr['participants'][$x]['name']){
$this->playerDetails['warFinalBattleWin'][$i] = $warArr['participants'][$x]['wins'];
}
}
}
I have 50 (or less) arrays from database and I need to return them in one array.
I'm currently using
$results = DB::table('coinflip_history')->where('ct', Auth::user()->steamid)->orWhere('t', Auth::user()->steamid)->orderByRaw('round_id DESC')->limit(50)->get();
$results = json_decode($results, true);
$i=1;
foreach ($results as $key => $value) {
if (!$value['winner']) $array[$i] = array('secret' => null, 'winning_string' => null, 'hash' => $value['hash'], 'timestamp' => $value['time']);
else $array[$i] = array('secret' => $value['secret'], 'winning_string' => $value['percentage'], 'hash' => $value['hash'], 'timestamp' => $value['time']);
$i++;
}
return array($array[1], $array[2], $array[3], $array[4], $array[5], $array[6], $array[7], $array[8], $array[9], $array[10], $array[11], $array[12], $array[13], $array[14], $array[15], $array[16], $array[17], $array[18], $array[19], $array[20], $array[21], $array[22], $array[23], $array[24], $array[25], $array[26], $array[27], $array[28], $array[29], $array[30], $array[31], $array[32], $array[33], $array[34], $array[35], $array[36], $array[37], $array[38], $array[39], $array[40], $array[41], $array[42], $array[43], $array[44], $array[45], $array[46], $array[47], $array[48], $array[49], $array[50]);
But if there are less than 50 arrays it's not working.
Is there any way to make it work automatically?
All arrays have indices.
It's just that kind of data data structure.
There is no way on PHP of generating an array without indices. It wouldn't be an array.
The only thing you are accomplishing with your code is generating an array starting on 1, and then creating a new array starting on 0.
Since both things are functionally equivalent, I guess that the problem exist down the line when you return an 1-based array.
So if you would do:
$array = [];
$results = json_decode($results, true);
foreach($results as $key => $value){
if(!$value['winner']) {
$array[] = [
'secret' => null,
'winning_string' => null,
'hash' => $value['hash'],
'timestamp' => $value['time']
];
}
else {
$array[] = [
'secret' => $value['secret'],
'winning_string' => $value['percentage'],
'hash' => $value['hash'],
'timestamp' => $value['time']
];
}
}
return $array;
You'd get what you need. This is 100% the same than what you are doing up there, but with less steps, and that works for any number of values on the returned $array.
// as simple as this
return $array;
First, im new in PHP so please bear with me.
I just want to add an array with the foreach loop but I can't.
if($size > 0)
{
$resultArray = array();
foreach($result as $hospital)
{
if($hospital)
{
$temp = array('result' => 'true',
'total' => $size,
'id' => $hospital['id'],
'name' => $hospital['name'],
'address' => $hospital['address'],
'telp' => $hospital['telp']);
$resultArray = array_merge_recursive($resultArray, $temp);
//$resultArray = array_splice($resultArray, $i, 0, $temp);
}
}
$this->response($resultArray, 200);
}
I tried to create a $temp array and merge it to the final result, and finally print that final result ($resultArray) to the response.
The array is successfully merged, but not in the way i want. This is the JSON result :
{"result":["true","true"],"total":[2,2],"id":["1","2"],"name":["test","keyword"],"address":["alamat test","alamat keyword"],"telp":["123456","789"]}
What i want is something like this :
-0 :{
result: "true"
total: 2
id: "1"
name: "test"
address: "alamat test"
telp: "123456"
}
-1 :{
result: "true"
total: 2
id: "2"
name: "test2"
address: "alamat tes 2t"
telp: "789"
}
So the response should be an array with 2 items, and each items has some items.
Please kindly help me, Thanks for your help.
It looks to me like you're trying to append an array, to an array, which can be done quite easily:
$resultArray = array();//outside the loop
//loop
$resultArray[] = array(
'result' => 'true',
'total' => $size,
'id' => $hospital['id'],
'name' => $hospital['name'],
'address' => $hospital['address'],
'telp' => $hospital['telp']
);
Job done. You could also use the array_push function, but that's a function. Functions equal overhead, and should, therefore be avoided (if it doesn't affect code readability). You use array_merge and array_merge_recursive if you want to combine arrays:
$foo = array(
array('bar' => 'zar')
);
$bar = array(
array('car' => 'far')
);
var_dump(
array_merge(
$foo,
$bar
)
);
The effect of array_merge here is comparable to:
foreach ($bar as $subArray)
$foo[] = $subArray;
Im not totally sure how you want your final array to be, but this will put it like $resultArray[0] = array( //temparray ) etc..:
if($size > 0){
$resultArray = array();
$i=0;
foreach($result as $hospital){
if($hospital){
$temp = array('result' => 'true',
'total' => $size,
'id' => $hospital['id'],
'name' => $hospital['name'],
'address' => $hospital['address'],
'telp' => $hospital['telp']);
$resultArray[$i][$temp];
$i++;
}
}
$this->response($resultArray, 200);
}
Replace this -
$resultArray = array_merge_recursive($resultArray, $temp);
With this -
$resultArray[] = $temp;