Laravel modify collection value with another value of another collection - json

I have a json file like this,
{
"unique_id_001":{
"price_1":264000,
"price_2":2178000,
"price_3":3168000,
"price_6":1089000,
"price_7":3168000
},
"unique_id_002":{
"price_1":264000,
"price_2":2178000,
"price_3":3168000,
"price_6":1089000,
"price_7":3168000
},
"unique_id_003":{
"price_1":264000,
"price_2":2178000,
"price_3":3168000,
"price_6":1089000,
"price_7":3168000
}
}
I convert it to collection and want to set those price_x to another collection.
public static function getOldPrices()
{
$storagePath = storage_path(self::PATH);
$file = File::get($storagePath);
$data = json_decode($file, true);
$collection = \App\Price::hydrate($data);
$oldPrices = $collection->flatten();
return $oldPrices;
}
public static function all()
{
$prices = \App\Price::all();
$old_prices = self::getOldPrices();
foreach ($prices as $price) {
foreach ($old_prices as $old_price) { // is there another way so I can remove this loop?
if ($price->id === $old_price->id) {
$price->price_1 = $old_price->price_1;
$price->price_2 = $old_price->price_2;
$price->price_3 = $old_price->price_3;
$price->price_6 = $old_price->price_6;
$price->price_7 = $old_price->price_7;
}
}
}
return $prices;
}
This code is working and could change the value of each price in $prices. But I wonder if there is other ways, because I used two foreach loop in this code, and I think it is not good.

I got another way using map()
Here is my updated code
$prices = $prices->map(function ($price) use ($oldPrices) {
if ($oldPrice = $oldPrices->firstWhere('id', $price->id)) {
$price->price_1 = $oldPrice->price_1;
$price->price_2 = $oldPrice->price_2;
$price->price_3 = $oldPrice->price_3;
$price->price_6 = $oldPrice->price_6;
$price->price_7 = $oldPrice->price_7;
}
return $price;
});

Related

how to replace part of object in Terraform

I'm constructing some objects to store the required information in Terraform
I just defined a variable and its value as below
vnetsettings = {
HUBVNET = {
VNET_Name = "co-vnet-01"
VNET_Location = "eastasia"
VNET_Resource_Group = "CoreInfra"
VNET_Address_Space = ["10.1.0.0/16","10.2.0.0/16"]
VNET_Tags = {
env = "prod"
application = "hub"
}
VNET_DNS_Servers = ["10.1.0.4","10.2.0.4"]
}
MGMTVNET = {
VNET_Name = "mgmt-vnet-01"
VNET_Location = "eastasia"
VNET_Resource_Group = "MGMT"
VNET_Address_Space = ["10.3.0.0/16","10.4.0.0/16"]
VNET_Tags = {
env = "prod"
application = "MGMT"
}
VNET_DNS_Servers = ["10.1.0.4","10.2.0.4"]
}
}
my question is how can i bulk replace some of the attributes in the object, like VNET_Resource_Group
below is the result i want, everything same as the one above, except for the VNET_Resource_Group
vnetsettings = {
HUBVNET = {
VNET_Name = "co-vnet-01"
VNET_Location = "eastasia"
VNET_Resource_Group = "replacedvalue"
VNET_Address_Space = ["10.1.0.0/16","10.2.0.0/16"]
VNET_Tags = {
env = "prod"
application = "hub"
}
VNET_DNS_Servers = ["10.1.0.4","10.2.0.4"]
}
MGMTVNET = {
VNET_Name = "mgmt-vnet-01"
VNET_Location = "eastasia"
VNET_Resource_Group = "replacedvalue"
VNET_Address_Space = ["10.3.0.0/16","10.4.0.0/16"]
VNET_Tags = {
env = "prod"
application = "MGMT"
}
VNET_DNS_Servers = ["10.1.0.4","10.2.0.4"]
}
}
What you can do is to create a local variable which is essentially a copy of the original object. Also, while making the copy you can replace an attribute from the original objects using the merge function.
locals {
vnetsettings_updated = {
for key, value in var.vnetsettings : key => merge(value, { VNET_Resource_Group = "replacedvalue" })
}
}
# Example usage of the updated object
output "vnetsettings" {
description = "VNET settings with updated VNET_Resource_Group"
value = local.vnetsettings_updated
}

Extract data from complex JSON in Flutter

I'm working in extract data from more complex JSON with unknown structure, its structure changes with operation ,
JSON sample link :http://afs-i.com/json.json
Kindly find my code here : http://afs-i.com/main.dart
Thanks in advance
Update:
I extracted the data using PHP code, you can find result here: http://afs-i.com/json.php
Kindly this is my PHP code:
$arraycars=array();
$y=json_decode($x);
// echo "<pre>";
// var_dump($y->tree[0]->children);
foreach ($y->tree[0]->children as $f) {
if(isset($f->vid)){
global $arraycars;
$arraycars[]=$f;
} elseif(isset($f->children)){
if(sizeof($f->children) > 0){
coolectcars($f->children);
}
}
}
function coolectcars($array){
// var_dump($array);
foreach ($array as $f) {
if(isset($f->vid)){
global $arraycars;
$arraycars[]=$f;
} elseif(isset($f->children)){
if(sizeof($f->children) > 0){
coolectcars($f->children);
}
}
}
}
echo json_encode($arraycars);
Update:2
I have problem now with null error for this code:
The error:
I/flutter ( 4264): NoSuchMethodError: The method 'forEach' was called on
null.
I/flutter ( 4264): Receiver: null
I/flutter ( 4264): Tried calling: forEach(Closure: (Children) => Null)
The code:
List<Children> cars = [];
Queue numQ = new Queue();
numQ.addAll(parsed["tree"][0]["children"]);
Iterator i = numQ.iterator;
while (i.moveNext()) {
// print("ddddddd ${i.current}");
if (i.current.containsKey("vid")) {
cars.add(new Children(
i.current['vid'], i.current['protocol'], i.current['datetime'],
i.current['gpss']));
} else {
Queue numQ = new Queue();
if (i.current["children"] != null) {
numQ.addAll(i.current["children"]);
// iterate(numQ);
List<Children> carse=[];
carse = iterate(numQ);
carse.forEach((data){
cars.add(data);
}) ;
}
}
}
cars.forEach((data) {
print(data.toString());
});
List<Children> iterate(Queue numQ) {
List<Children> cars=new List<Children>();
Iterator i = numQ.iterator;
while (i.moveNext()) {
print("ddddddd ${i.current}");
if (i.current.containsKey("vid")) {
cars.add(new Children(
i.current['vid'], i.current['protocol'], i.current['datetime'],
i.current['gpss']));
} else {
if (i.current["children"] != null) {
Queue numQ = new Queue();
numQ.addAll(i.current["children"]);
List<Children> carse=[];
carse = iterate(numQ);
carse.forEach((data){
cars.add(data);
}) ;
}
}
return cars;
}
}
I prefer using built_value to do json deserialization/ serialization. It's more elegant. You don't need to write down fromJson by yourself. built_value will generate deserializers / serializer for you. You can check built_value's github or this and this articles.
A good place for convert JSON to dart here
hats to reddit url
just copy your json into the textbox and generate, it will auto generate for you.
With this, you can call fromJson and feed it the json, then you can also get auto complete for it
eg: usage
final response =
await http.get('http://afs-i.com/json.json');
if (response.statusCode == 200) {
final Autogenerated respJson = Autogenerated.fromJson(json.decode(response.body));
print(respJson.tree[0].userId);
}
insert this import 'dart:convert';
into your widget file at top.
lets say you have your json in
var response
then
var jsonDecoded= json.decode(response);
now you can get name and user_id like this:
var user_id= jsonDecoded["tree"][0]["user_id"];
var name = jsonDecoded["tree"][0]["name"];
NOTE : I get these values from the first object (0 index). If you want values for each object , you can loop to get it.
The final answer i reach:
final parsed = json.decode(response.body);
List<Children> cars = [];
Queue numQ = new Queue();
numQ.addAll(parsed["tree"][0]["children"]);
Iterator i = numQ.iterator;
while (i.moveNext()) {
if (i.current.containsKey("vid")) {
cars.add(new Children(
i.current['vid'],
i.current['datetime'],
));
} else {
Queue numQ = new Queue();
if (i.current["children"].toString() != "[]") {
numQ.addAll(i.current["children"]);
List<Children> carse = [];
carse = iterate(numQ);
carse.forEach((data) {
cars.add(data);
});
}
}
}
List<Children> iterate(Queue numQ) {
List<Children> cars = new List<Children>();
Iterator i = numQ.iterator;
while (i.moveNext()) {
if (i.current.containsKey("vid")) {
if (i.current.containsKey("vid")) {
cars.add(new Children(
i.current['vid'],
i.current['datetime'],
));
}
} else {
if (i.current["children"].toString() != "[]") {
Queue numQ = new Queue();
if (i.current["children"].toString() != "[]") {
numQ.addAll(i.current["children"]);
List<Children> carse = [];
carse = iterate(numQ);
carse.forEach((data) {
cars.add(data);
});
}
}
}
return cars;
}

Adding base64 string to JSON invalidates it

I am creating a JSON Array having a byte64 string data. This is an invalid JSON but when I remove the displaypic value by some normal string the JSON is valid. Please help me with this. Is there any other way to work with images that has to be parsed on cross platforms. How do I deal with this byte 64 string.
It's a long data so can't add here.. The body limit is 30000. Please see this link for the JSON.
CODE THAT CREATES JSON
function checkLogin_post()
{
//$responsedata = array();
if($this->post('useremail') && $this->post('password'))
{
$useremail = $this->post('useremail');
$password = $this->post('password');
$this->load->model('loginmodel');
$table_data = $this->loginmodel->checkLogin($useremail);
if (sizeof($table_data) != 0)
{
foreach ($table_data as $data)
{
if($password == $data->password)
{
$responsedata["firstname"] = $data->firstname;
$responsedata["lastname"] = $data->lastname;
$responsedata["email"] = $data->email;
$responsedata["userid"] = $data->userid;
$responsedata["displaypic"] = $data->displaypic; //THIS IS THE BASE64
$responsedata["ispersonaldetailsfilled"] = $data->ispersonaldetailsfilled;
$responsedata["isexpertisedetailsfilled"] = $data->isexpertisedetailsfilled;
$responsedata["isprofessionaldetailsfilled"] = $data->isprofessionaldetailsfilled;
$this->response(array("success"=>$responsedata), 200);
//$this->response($responsedata, 200);
}
else
{
$this->response(array("error"=>"Password not matched"), 200);
}
}
}
else
{
$this->response(array("error"=>"User not found"), 200);
}
}
else
{
if($this->post('useremail') == "")
{
$this->response(array("error"=>"Useremail can't be null"),200);
}
if($this->post('password') == "")
{
$this->response(array("error"=>"Password can't be null"),200);
}
}
}
It was just missing a brace at the end. Here's your corrected JSON
Always use tools to validate your json before posting a question. I personally like http://pro.jsonlint.com

Reuse sortCompareFunction across DataGridColumns in AS3

I put together a DataGrid using the following functions
public function get dataGridColumns():Array {
var dataGridColumnArray:Array = [];
dataGridColumnArray.push(createDataGridColumn(col1, "field1", 0.17, sortStrings));
dataGridColumnArray.push(createDataGridColumn(col2, "field2", 0.17, sortStrings));
dataGridColumnArray.push(createDataGridColumn(col3, "field3", 0.17, sortStrings));
return dataGridColumnArray;
}
private static function createDataGridColumn(columnName:String, dataField:String, width:Number,sortCompareFunction:Function = null):DataGridColumn {
var column:DataGridColumn = new DataGridColumn(columnName);
column.dataField = dataField;
column.width = width;
column.sortCompareFunction = sortCompareFunction;
return column
}
private function sortStrings(a:Object, b:Object, fields:Array = null):int{
if(a.toString().toLowerCase() > b.toString().toLowerCase()){
return 1;
}else if(a.toString().toLowerCase() < b.toString().toLowerCase()){
return -1;
}else{
return 0;
}
}
Since my dataProvider is an array of data objects I run into the problem that a and b in the sort function are objects, and I want to somehow pass the data field (column title) into the sort so I can check the correct object property all using one sort function so it would look something like:
private function sortStrings(a:Object, b:Object, field:String):int{
if(a.field.toLowerCase() > b.field.toString().toLowerCase()){
return 1;
}else if(a.field.toString().toLowerCase() < b.field.toString().toLowerCase()){
return -1;
}else{
return 0;
}
}
I have not figured out a good way to do this yet, and worst case scenario I have 6 extremely similar sort functions.
you can make a comparators factory function, which will return closures, enclosing the field name:
private function createComparatorFor(field:String):Function {
return function (a:Object, b:Object, fields:Array = null):int{
const aField:String = a[field].toString().toLowerCase();
const bField:String = b[field].toString().toLowerCase();
if (aField > bField) {
return 1;
}
if (aField < bField) {
return -1;
}
return 0;
}
}
and use it like this:
dataGridColumnArray.push(createDataGridColumn(
col1, "field1", 0.17, createComparatorFor("field1")));
untested, but should work

Retrieving array of Controllers/Actions

Is it possible in Yii2 to retrieve an array containing all controllers and actions for the whole application?
I finally ended up with:
protected function actionGetcontrollersandactions()
{
$controllerlist = [];
if ($handle = opendir('../controllers')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && substr($file, strrpos($file, '.') - 10) == 'Controller.php') {
$controllerlist[] = $file;
}
}
closedir($handle);
}
asort($controllerlist);
$fulllist = [];
foreach ($controllerlist as $controller):
$handle = fopen('../controllers/' . $controller, "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (preg_match('/public function action(.*?)\(/', $line, $display)):
if (strlen($display[1]) > 2):
$fulllist[substr($controller, 0, -4)][] = strtolower($display[1]);
endif;
endif;
}
}
fclose($handle);
endforeach;
return $fulllist;
}
I started with the answer from Andreas Hinderberger, and just fine tuned it. I ended up with something like this:
It uses FileHelper to get all the files recursively, which is useful if you are extending controllers from base classes. It also formats the controller-id/action-id using Inflector::camel2id so they will match your routes.
public function getAllControllerActions()
{
$controllers = \yii\helpers\FileHelper::findFiles(Yii::getAlias('#app/controllers'), ['recursive' => true]);
$actions = [];
foreach ($controllers as $controller) {
$contents = file_get_contents($controller);
$controllerId = Inflector::camel2id(substr(basename($controller), 0, -14));
preg_match_all('/public function action(\w+?)\(/', $contents, $result);
foreach ($result[1] as $action) {
$actionId = Inflector::camel2id($action);
$route = $controllerId . '/' . $actionId;
$actions[$route] = $route;
}
}
asort($actions);
return $actions;
}
As far as I know Yii 2 doesn't have any built-in methods to achieve this. You can only get the current controller and its action.
What's the purpose of it? If you really need this you can write such functionality by yourself.
To get all controllers you should search for a files ending with Conroller. And they can be located in different places of application. For example in nested folders, modules, nested modules, etc. So there is more than just one place for search.
To get all actions you should search for all methods prefixed with action in each controller.
Also don't forget about attached actions in controller actions() method. In framework they are usually ending with Action, take a look for example at rest actions. But no one forces you to name it like that, so there is possibility that some external actions can just have different naming convention (for example if you working in team and don't follow this convention).
And you probably need to exclude such folders as vendor.
So it's not trivial task, but possible with some inaccuracies. I just don't get it what's the point of that.
Follow example walk trought all modules and collect all modules controller actions (no tested):
<?php
$controllerDirs = [];
$controllerDirs[] = \Yii::getAlias('#app/controllers');
if ($commonControllerDir = \Yii::getAlias('#common/controllers', false)) {
$controllerDirs['common'] = $commonControllerDir;
}
foreach (\Yii::$app->modules as $moduleId => $module) {
/*
* get module base path
*/
if (method_exists($module, 'getBasePath')) {
$basePath = $module->getBasePath();
} else {
$reflector = new \ReflectionClass($module['class']);
$basePath = StringHelper::dirname($reflector->getFileName());
}
$basePath .= '/controllers';
$controllerDirs[$moduleId] = $basePath;
}
$actions = [];
foreach ($controllerDirs as $moduleId => $cDir) {
$actions[$moduleId][$cDir] = actionGetcontrollersandactions($cDir);
}
print_r($actions);
function actionGetcontrollersandactions($controllerDir) {
$controllerlist = [];
if ($handle = opendir($controllerDir)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && substr($file, strrpos($file, '.') - 10) == 'Controller.php') {
$controllerlist[] = $file;
}
}
closedir($handle);
}
asort($controllerlist);
$fulllist = [];
foreach ($controllerlist as $controller):
$handle = fopen($controllerDir . '/' . $controller, "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (preg_match('/public function action(.*?)\(/', $line, $display)):
if (strlen($display[1]) > 2):
$fulllist[substr($controller, 0, -4)][] = strtolower($display[1]);
endif;
endif;
}
}
fclose($handle);
endforeach;
return $fulllist;
}