How to loop through an array without repeating? - php

I'm trying to get data from API and I receive this
[
{
"service": 1,
"name": "Followers",
"type": "Default",
"category": "First Category",
"rate": "0.90",
"min": "50",
"max": "10000"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
}
]
I want to get the category for each service without repeating the same category twice.
Edited*
I have this code
$servers = $this->Setting->Loop('api','WHERE is_active = 1');
foreach($servers->result() as $server){
foreach($this->Api_Connect->services($server->api_url, $server->api_key) as $item) {
echo '<option data-server='.$server->id.' data-percent='.$server->addon_percent.' data-price='.$item['rate'].' data-min='.$item['min'].' data-max='.$item['max'].' value="'.$item['service'].'">- '.$item['name'].'</option>';
}
}
which connect to each server with api url and key and return with the services.

We can set a new array, and push categories in the new array, and check if the new value does not exist do so:
$data = '[
{
"service": 1,
"name": "Followers",
"type": "Default",
"category": "First Category",
"rate": "0.90",
"min": "50",
"max": "10000"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
}
]';
$data = json_decode($data, true);
$category = array();
foreach ($data as $value) {
if (!array_search($value["category"], $category)) {
array_push($category, $value["category"]);
}
}
var_dump($category);
Output
array(2) {
[0]=>
string(14) "First Category"
[1]=>
string(15) "Second Category"
}
Edit:
Based on Andreas's advice, we can also use if(in_array()) in the loop using:
$category[$value["category"]] = $value["category"];
which is much more efficient.

$array = [];
foreach($object as $key => $value) {
// object is data you receive from API
array_push($array,$value->category);
}
// to get unique values
$array = array_unique($array);
I hope this code solve your problem

The fastest method is to use array_column.
Array_column will isolate one column of the array.
The third parameter of array_column will set the key name.
This is what we want.
Because you don't want duplicates we set something as value and "category" as key.
This means it will loop once and overwrite the keys that is duplicated.
The other methods posted here will need to check if the item is already added to the list or using array_unique which needs to compare each item with every other item, that is a slow function when you give it a large array.
$data = '[
{
"service": 1,
"name": "Followers",
"type": "Default",
"category": "First Category",
"rate": "0.90",
"min": "50",
"max": "10000"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
}
]';
$data = json_decode($data, true);
$category = array_column($data, "rate", "category");
var_dump($category);
Output of this:
// Note it's only the keys we want, the values are not interesting
array(2) {
["First Category"]=>
string(4) "0.90"
["Second Category"]=>
string(1) "8"
}

$jsonResponse='[
{
"service": 1,
"name": "Followers",
"type": "Default",
"category": "First Category",
"rate": "0.90",
"min": "50",
"max": "10000"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
}
]';
$listData=json_decode(jsonResponse,true);
foreach($listData as $valRes){
echo $valRes['category'];
}
you can get category

Related

Delete JSON item inside an sub-array

I wonder how can I unset the target array whenever i wanted in PHP. It's a product list and the procedure im planning if i want to delete a products. Here's the JSON structure
{
"Merchant": "SAMHONEY",
"date": 1632482493,
"archive": "true",
"extra": "Byahe",
"data": [
{
"product-image": "https:\/\/mobi.asia\/assets\/abunjing-stand.png",
"name": "Sample Product",
"des": "Byahe Palawan Merchant Dashboard v.1.1",
"price": "26"
},
{
"product-image": "https:\/\/mob.asia\/assets\/abunjing-stand.png",
"name": "Sample Product 2",
"des": "Byahe Palawan Merchant Dashboard v.1.1",
"price": "99"
},
{
"product-image": "https:\/\/mob.asia\/01162020\/images\/storage\/1632200295.png",
"name": "Product C",
"des": "Great coffee",
"price": "3"
},
{
"product-image": "https:\/\/mob.asia\/01162020\/images\/storage\/1632200342.png",
"name": "Product A",
"des": "Caramel Coffee",
"price": "4"
}
]
}
What I done in PHP is this
$pos = $_POST['position'];
$jsn = file_get_contents('../datamer/archives/'.$sbd.".json");
$arr = json_decode($jsn, true);
$acc = $arr["data"];
unset($acc[$pos]);
$arr["data"] =$acc;
file_put_contents('../datamer/archives/'.$sbd.".json",json_encode($arr,JSON_PRETTY_PRINT));
And the output is it was re-structuring the JSON into this.Which not im expecting
{
"Merchant": "SAMHONEY",
"date": 1632482493,
"archive": "true",
"extra": "Byahe",
"data": {
"0": {
"product-image": "https:\/\/mobile.byahe.asia\/assets\/abunjing-stand.png",
"name": "Sample Product",
"des": "Byahe Palawan Merchant Dashboard v.1.1",
"price": "26"
},
"2": {
"product-image": "https:\/\/mobile.byahe.asia\/01162020\/images\/storage\/1632200295.png",
"name": "Product C",
"des": "Great coffee",
"price": "3"
},
"3": {
"product-image": "https:\/\/mobile.byahe.asia\/01162020\/images\/storage\/1632200342.png",
"name": "Product A",
"des": "Caramel Coffee",
"price": "4"
}
}
}
Kindly enlighten me to this. I'm still learning,. Thanks in advance for the attention. Well appreciated.

Sorting only a part of object/array in PHP

I've been struggling around this for a while now and can't seem to get the right algorithm.
What I want is to sort this:
$variable = '{
"0": {
"id": "0",
"code": "main_colour",
"label": "Main Colour",
"options": [{
"id": "825",
"label": "White",
"products": ["1", "2", "3"]
}, {
"id": "840",
"label": "Cream",
"products": ["3", "4", "5"]
}],
"position": "0"
},
"2": {
"id": "0",
"code": "size",
"label": "Size",
"options": [{
"id": "825",
"label": "S",
"products": ["1", "2", "3"]
}, {
"id": "840",
"label": "M",
"products": ["3", "4", "5"]
}],
"position": "0"
}
}';
And the output would be
$variable = '{
"0": {
"id": "0",
"code": "main_colour",
"label": "Main Colour",
"options": [{
"id": "840",
"label": "Cream",
"products": ["3", "4", "5"]
},{
"id": "825",
"label": "White",
"products": ["1", "2", "3"]
}],
"position": "0"
},
"2": {
"id": "0",
"code": "size",
"label": "Size",
"options": [{
"id": "840",
"label": "M",
"products": ["3", "4", "5"]
}, {
"id": "825",
"label": "S",
"products": ["1", "2", "3"]
}],
"position": "0"
}
}';
So basically it should be sorted using the label inside the "options" without affecting the other fields. I've been trying usort and tried different algorithms but to no avail.
Current code that sorts only the outside "label" and not the inner label:
function optionsSort($a, $b) {
return strcmp($a['options'][0]['label'], $b['options'][0]['options']['label']);
}
usort($variable, "optionsSort"));
Here's the code:
// your array
$variable = '{
"0": {
"id": "0",
"code": "main_colour",
"label": "Main Colour",
"options": [{
"id": "825",
"label": "White",
"products": ["1", "2", "3"]
}, {
"id": "840",
"label": "Cream",
"products": ["3", "4", "5"]
}],
"position": "0"
},
"2": {
"id": "0",
"code": "size",
"label": "Size",
"options": [{
"id": "825",
"label": "S",
"products": ["1", "2", "3"]
}, {
"id": "840",
"label": "M",
"products": ["3", "4", "5"]
}],
"position": "0"
}
}';
$a = json_decode($variable);
foreach ($a as $item) {
// sorting function
usort($item->options, function($a, $b) { return strcmp($a->label, $b->label); });
}

Display some parts of a file written in json

Below is my JSON file:
{
"example": "1",
"example2": 2,
"text": "3",
"info": {
"agent": 4,
"sum": 5,
"collection": [{
"Name": "6",
"Pic": "7"
} {
"Name": "8",
"Pic": "9"
}, {
"Name": "10",
"Pic": "11"
}]
}
}
How would I display each 'name' and 'pic' I think I need to use a foreach loop but don't know how to.
This is all the code I have:
$data = json_decode(file_get_contents('http://linktojson.com'));
echo $data['info']['collection'][0]['Name'];
echo $data['info']['collection'][0]['Pic'];
This should work
$data = json_decode(file_get_contents('http://linktojson.com'));
echo "<pre>".print_r($data,1)."</pre>";
foreach($data->info->collection as $key){
echo $key->Pic;
echo $key->Name;
}
Valid JSON
{
"example": "1",
"example2": 2,
"text": "3",
"info": {
"agent": 4,
"sum": 5,
"collection": [{
"Name": "6",
"Pic": "7"
}, {
"Name": "8",
"Pic": "9"
}, {
"Name": "10",
"Pic": "11"
}]
}
}

Elasticsearch Updating / Deleting Nested

I've gone through a few examples and documentations and kind find a solution update a nested object in the this result set.
I can add one (if one does not exist)
I can append to it (if one does exist)
Can't figure out how to delete a selected entry.
Is there a method I can use (using the php client) to add an entry if it does not exist / update an entry if it does exist / delete the second entry.
I'm inheriting this problem and am new to Elastic search.
Thanks.
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "products",
"_type": "categories",
"_id": "AUpRjtKZfXI7LIe9OpNx",
"_score": 1,
"_source": {
"name": "Primary",
"description": "Primary Category",
"slug": "Primary",
"created": "2014-12-16 00:25:22",
"parent": [
{
"name": "First One",
"description": "Test",
"id": "ae74ea4e2e865ed3fd60c18a06e69c65",
"slug": "first-one"
},
{
"name": "Second One",
"description": "Testing Again",
"id": "c8dbe5143c8dfd6957fa33e6cea7a0a8",
"slug": "second-one"
}
]
}
}
]
}
}
Do you want to do all three in the same operation?
Deleting the second nested object is achieved through a script which removes the second element:
PUT /products
{
"mappings": {
"categories": {
"properties": {
"parent": {
"type": "nested",
"properties": {
"name": { "type": "string" },
"description": { "type": "string" },
"id": { "type": "string", "index": "not_analyzed" },
"slug": { "type": "string" }
}
}
}
}
}
}
PUT /products/categories/1
{
"name": "Primary",
"description": "Primary Category",
"slug": "Primary",
"created": "2014-12-16 00:25:22",
"parent": [
{
"name": "First One",
"description": "Test",
"id": "ae74ea4e2e865ed3fd60c18a06e69c65",
"slug": "first-one"
},
{
"name": "Second One",
"description": "Testing Again",
"id": "c8dbe5143c8dfd6957fa33e6cea7a0a8",
"slug": "second-one"
}
]
}
POST /products/categories/1/_update
{
"script" : "ctx._source.parent.remove(1)",
"lang": "groovy"
}
GET /products/categories/1
So in PHP code (using the official PHP client), the update would look like:
$params = [
'index' => 'products',
'type' => 'categories',
'id' => 1,
'body' => [
'script' => 'ctx._source.parent.remove(1)',
'lang' => 'groovy'
]
];
$result = $client->update($params);

remove unnecessary hierarchy from json output

I am building an admin backend for an android app. My code provides a json output which the android developer then uses in his app. The developer asked me if it is possible to reduce the hierarchy level in the json output
as in remove the highlighted []0 and put the contents directly inside the []data instead.
This is my current php code
if($type == 1 ) //Handle item display
{
try
{
$query = "SELECT category FROM category";
$result= $DBH->query($query);
while($row = $result->fetch(PDO::FETCH_ASSOC))
{
$cat = $row['category'];
$query1 = "SELECT * FROM item WHERE catagory='$cat'";
$value = $DBH->query($query1);
if($row1 = $value->fetchAll(PDO::FETCH_OBJ)){
$main[] = array('data'=>array($row1));
}
else
{
$main[] = array('data'=>array('catagory'=>$row['category']));
}
}
echo json_encode($main);
$result->closeCursor(); //Close database connection free resources
$DBH = null;
}
catch(PDOException $e){
print $e->getMessage ();
die();
}
}
And the json output being generated
[
{
"data": [
[
{
"id": "2",
"name": "rice",
"price": "20",
"description": "Plain Rice",
"image": "4106_rice.jpg",
"time": "12 mins",
"catagory": "Lunch",
"subcat": ""
},
{
"id": "3",
"name": "item 1",
"price": "32",
"description": "item 1 description",
"image": "1370_2Ckjikljklkljh.jpg",
"time": "10",
"catagory": "Lunch",
"subcat": "Chicken Soup"
},
{
"id": "4",
"name": "hello",
"price": "10",
"description": "fgsdjfsfsdj",
"image": "",
"time": "76",
"catagory": "Lunch",
"subcat": ""
}
]
]
},
{
"data": {
"catagory": "Dinner"
}
},
{
"data": {
"catagory": "Soup"
}
},
{
"data": {
"catagory": "Test"
}
}
]
I am not very sure if I can make the changes he asked or if it is possible. Is it doable?
Your json structure is inconsistent and try this approach, will be easier for the developer to parse
{
"response": [
{
"data": [
{
"id": "2",
"name": "rice",
"price": "20",
"description": "Plain Rice",
"image": "4106_rice.jpg",
"time": "12 mins",
"catagory": "Lunch",
"subcat": ""
},
{
"id": "3",
"name": "item 1",
"price": "32",
"description": "item 1 description",
"image": "1370_2Ckjikljklkljh.jpg",
"time": "10",
"catagory": "Lunch",
"subcat": "Chicken Soup"
},
{
"id": "4",
"name": "hello",
"price": "10",
"description": "fgsdjfsfsdj",
"image": "",
"time": "76",
"catagory": "Lunch",
"subcat": ""
}
]
},
{
"data": [
{
"catagory": "Dinner"
}
]
},
{
"data": [
{
"catagory": "Soup"
}
]
},
{
"data": [
{
"catagory": "Test"
}
]
}
]
}

Categories