How to delete elements from array from certain value on? - php

I have an array in PHP and I don't know how to delete all the elements from every array element from certain character on, icluding that character. Is there a way to do this?
array(1092) {
["Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite"]=>
int(124)
}
In my example I want to delete all text from "#####", including "#####" to the end, foreach array element. Is this possible? Or is there a PHP function for this?
UPDATE
My result should look like this:
array(1092) {
["Piper;Rosii;Sare;Test;Vinete]=>
int(124)
}

You can use array_walk to apply the substr and strpos to each element:
$array = [
'23845637;54634;345;3453345;#####morestuff',
'234234#####34596078345j34534534',
'34343245dfg#####asdfsadf;23452345;sdfsdf;345345'
];
array_walk($array, function(&$value, $key) {
$value = substr($value, 0, strpos($value, '#####'));
});
var_dump($array);
Will result in:
array(3) {
[0]=>
string(27) "23845637;54634;345;3453345;"
[1]=>
string(6) "234234"
[2]=>
string(11) "34343245dfg"
}
This will modify the original array.
For each element in the array, we search for the position of '#####' in the string and only take the part from 0 to the position in the string where '#####' occurs.

This will do that by looping through the array exploding the key by ##### and adding it to a new array. I did it in a loop in case your array is bigger than 1
<?php
$oldArray = array("Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite" => 124);
$newArray = array();
foreach ($oldArray as $key => $row) {
$newKey = explode('#####', $key);
$newArray[$newKey[0]] = $row;
}
var_dump($newArray);

You can use substr and strpos to add the new entry and then unset the old entry in the array like this example:
$array = array(
"Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite" => 124
);
foreach ($array as $key => $value) {
$array[substr($key, 0, strpos($key, '#####'))] = $value;
unset($array[$key]);
}
var_dump($array);
Will result in:
array(1) {
["Piper;Rosii;Sare;Test;Vinete"]=>
int(124)
}

Related

How correctly to process an arrays?

There are two arrays:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
The number of elements in the second array is less than or equal to the first array.
Sort out the first array and the second array, if the elements of the second array are contained at the end of the elements of the first array, sort the array in this form:
Array
(
[0] => w_ord
[1] => tech
[2] => care
[3] => k_ek
[4] => l_ol
[5] => wi_ld
[6] => re_gex
)
Important: the elements of the second array are never repeated, and can go in any order. If in the second element there is no end of the element of the first array, then set the value of the element of the first array.
I do this:
foreach($arr2 as $val) {
$strrepl[$val] = "_".$val;
}
foreach($arr1 as $key => $val) {
$arr3[$key] = str_replace(array_keys($strrepl), $strrepl, $val);
}
print_r($arr3);
But I'm not sure that this is the right approach, what will you advise?
Hmm, let's see ... purely functional 'cause you know :D
function ends($str) {
return function($suffix) use($str) {
return mb_strlen($str) >= mb_strlen($suffix)
&& mb_substr($str, mb_strlen($suffix) * -1) === $suffix;
};
}
$result = array_map(function($item) use($arr2) {
$filter = ends($item);
$suffixes = array_filter($arr2, $filter);
if (empty($suffixes)) {
return $item;
}
// This only cares about the very first match, but
// is easily adaptable to handle all of them
$suffix = reset($suffixes);
return mb_substr($item, 0, mb_strlen($suffix) * -1) . "_{$suffix}";
}, $arr1);
Surprisingly, this one was quite fun to execute.
Since you went very specific on end of the element, I decided to use RegEx for that.
Here is my approach:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
foreach ($arr2 as $find) {
foreach ($arr1 as $key => $element) {
$arr1[$key] = preg_replace('/' . $find . '$/', '_' . $find, $element);
}
}
For every element of the second array (since they are not repeated), I go through every element of the first array and check if the value can be found at the end of the element of the second array using the $ anchor from RegEx which forces it to look it from the end of the string.
This way the $arr1 will have exactly what you expect.
[Edit]
Following the scape suggestion from #aefxx and improving variable names.
You can use preg_grep which is regex on arrays.
This code will also make sure it can output more than one matching word from $arr1.
$arr1 = ['word', 'chord', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$keys=[];
foreach($arr2 as $val){
$matches = preg_grep("/.+" . preg_quote($val) . "/", $arr1);
$keys = array_merge($keys, array_keys($matches)); // save keys of matched words
foreach($matches as $key => $m) $new[$val][] = str_replace($val, "_$val", $arr1[$key]);
}
$new['unmatched'] = array_diff_key($arr1, array_flip($keys)); // add unmatched words
var_dump($new);
Output:
array(6) {
["ord"]=>
array(2) {
[0]=>
string(5) "w_ord"
[1]=>
string(6) "ch_ord"
}
["ek"]=>
array(1) {
[0]=>
string(4) "k_ek"
}
["ol"]=>
array(1) {
[0]=>
string(4) "l_ol"
}
["ld"]=>
array(1) {
[0]=>
string(5) "wi_ld"
}
["gex"]=>
array(1) {
[0]=>
string(6) "re_gex"
}
["unmatched"]=>
array(2) {
[2]=>
string(4) "tech"
[3]=>
string(4) "care"
}
}
https://3v4l.org/gfUea
You can try this.I think it is easy to understand :
$arr1=['word','tech','care','kek','lol','wild','regex'];
$arr2=['ord','ek','ol','ld','gex','ss'];
foreach($arr1 as $key=>$fullword){
foreach($arr2 as $substr){
$arr1[$key]=preg_replace('/' . $substr . '$/', '_' . $substr, $fullword,-1,$count);
if($count) break;
}
}
i go throught the array of fullword and as soon as i find a match i stop the search.
Another approach can be to create complex regex beforehand (using implode and preg_quote for safety) and use it for replacement inside array_map callback:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$regex = '/(' . implode('|', array_map('preg_quote', $arr2)) . ')$/';
$result = array_map(function ($word) use ($regex) {
return preg_replace($regex, '_$1', $word);
}, $arr1);
Here is the demo.

how to take array with specific char?

i have array
Example :
array(3) { [0]=> string(6) "{what}" [1]=> string(5) "[why]" [2]=> string(5) "(how)" }
and then how to take array with specific char ("{") ?
Is my understanding here correct? You want to get items in array that has a "{" Character. Then why not just loop over it and check the item if it has that character and push it in a new array.
$array_with_sp_char = array();
foreach ($arr_items as $item) {
if (strpos($item, '{') !== FALSE) {
array_push($array_with_sp_char, $item);
}
}
Just iterate through your array and filter out the values you are interested in, in your case i guess it's the values that contain the Char "{"
A possible implementation:
$result = array_filter($your_array, function($value) {
return preg_match('/{/', $value);
});
Use a combination of array_filter and strpos:
$array = [
"{what}",
"[why]",
"(how)"
];
$array = array_filter($array, function($value) {
return strpos($value, '{') !== false;
});
print_r($array);
That will give you:
Array
(
[0] => {what}
)

Removing a JSON record from .json file with PHP

I have a json file looking like this :
[["{\"id\":1474721566304,\"name\":\"GGG\",\"brand\":\"GG\",\"price\":\"3\"}"],["{\"id\":1474721570904,\"name\":\"GGGH\",\"brand\":\"GGH\",\"price\":\"4\"}"],["{\"id\":1474721574188,\"name\":\"GGGH\",\"brand\":\"GGHH\",\"price\":\"5\"}"]]
What I am trying to do is to remove a record from it by it's id. For this purpose I have the following PHP code :
<?php
$string = file_get_contents("products.json");
$json_a = json_decode($string, true); //turning JSON-string into an array containing JSON-strings
$arr = array();
foreach ($json_a as $key) {
array_push($arr,json_decode($key[0],true)); //and here you turning each of the JSON-strings into objects themselves
}
$data= $_GET['data'];
$i=0;
foreach($arr as $element) {
if($data == $element["id"]){
unset($arr[$i]);//removing the product by ID
}
$i++;
}
var_dump($arr);
$arr2 = array();
foreach ($arr as $key) {//trying to make it look like the original json.
array_push($arr2,json_decode($key[0],true));
}
//var_dump($arr2);
echo json_encode($arr2);
?>
What I am getting from this code is :
array(2) { [0]=> array(4) { ["id"]=> float(1474721566304) ["name"]=> string(3) "GGG" ["brand"]=> string(2) "GG" ["price"]=> string(1) "3" } [1]=> array(4) { ["id"]=> float(1474721570904) ["name"]=> string(4) "GGGH" ["brand"]=> string(3) "GGH" ["price"]=> string(1) "4" } }
I am really out of ideas how to make this array look like my original JSON shown first on this post. I tried many different things, but I couldn't make it work. My idea is after removing the record by it's ID to replace the old JSON with the new one that I am trying to construct here.
I am new to php and I'd appreciate any input on my issue.
First of all - your input JSON is wrong:
array (size=3)
0 =>
array (size=1)
0 => string '{"id":1474721566304,"name":"GGG","brand":"GG","price":"3"}' (length=58)
1 =>
array (size=1)
0 => string '{"id":1474721570904,"name":"GGGH","brand":"GGH","price":"4"}' (length=60)
2 =>
array (size=1)
0 => string '{"id":1474721574188,"name":"GGGH","brand":"GGHH","price":"5"}' (length=61)
You don't have 'id' nor 'name', 'GGG' and other keys. You just have one long string. You should remove unnecessary quotation marks. After that your JSON should look like this:
[[{"id":1474721566304,"name":"GGG","brand":"GG","price":"3"}],[{"id":1474721570904,"name":"GGGH","brand":"GGH","price":"4"}],[{"id":1474721574188,"name":"GGGH","brand":"GGHH","price":"5"}]]
And finally, your PHP code can be much shorter:
$json = "[[{\"id\":1474721566304,\"name\":\"GGG\",\"brand\":\"GG\",\"price\":\"3\"}],[{\"id\":1474721570904,\"name\":\"GGGH\",\"brand\":\"GGH\",\"price\":\"4\"}],[{\"id\":1474721574188,\"name\":\"GGGH\",\"brand\":\"GGHH\",\"price\":\"5\"}]]";
$input = json_decode($json, true);
$output = array();
foreach($input as $element) { //you don't need to declare yet another array, just use the one you already have
if($_GET['data'] != $element[0]["id"]){ //and not unset, just add to new array if you want
$output[] = $element; //shorter and faster than array_push()
}
}
echo json_encode($output);
Try this code:
$string = file_get_contents("product.json");
$json_a = json_decode($string, true); //turning JSON-string into an array containing JSON-strings
$arr = array();
foreach ($json_a as $key) {
array_push($arr,json_decode($key[0],true)); //and here you turning each of the JSON-strings into objects themselves
}
$data= 0;
$i=0;
foreach($arr as $element) {
if($data == $element["id"]){
unset($arr[$i]);//removing the product by ID
}
$i++;
}
// print_r($arr);
$arr2 = array();
foreach($arr as $key => $val) {
$arr2[][] = $val;
}
//var_dump($arr2);
echo json_encode($arr2);

PHP remove element from array issue

I am doing with Laravel 5. And the problem I am facing is that I have an array in session and now I want to remove a single element from that array and for the sake I am using array_diff function.
When I get array from session it's in the form like:
["4","5","6"]
But when I try to remove element '5' from array it deforms the array and the result then is:
{"0":"4","2":"6"}
My code is:
array_diff($arr, array(5))
The result is same with unset([$index]) also.
The real code:
Session::push('compare.products', $id);
$compare = Session::get('compare');
if(($key = array_search($id, $compare['products'])) !== false) {
unset($compare['products'][$key]);
return $compare['products'];
}
If you want to keep correct indexes you have to call array_values after the unset.
In your case, it will be :
Session::push('compare.products', $id);
$compare = Session::get('compare');
if(($key = array_search($id, $compare['products'])) !== false) {
unset($compare['products'][$key]);
return array_values($compare['products']);
}
In a general case, it's :
$array = array(0, 1, 2, 3);
unset($array[2]);
$array = array_values($array);
var_dump($array);
/* array(3) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(3)
} */
https://stackoverflow.com/a/369761/4682796

php loop through array

I am trying to get certain values from an array but got stuck. Here is how the array looks:
array(2) {
[0]=>
array(2) {
["attribute_code"]=>
string(12) "manufacturer"
["attribute_value"]=>
string(3) "205"
}
[1]=>
array(2) {
["attribute_code"]=>
string(10) "silhouette"
["attribute_value"]=>
array(1) {
[0]=>
string(3) "169"
}
}
}
So from it I would like to have attribute_values, and insert it into a new array, so in this example I need 205 and 169. But the problem is that attribute_value can be array or string. This is what I have right now but it only gets me the first value - 205.
foreach ($array as $k => $v) {
$vMine[] = $v['attribute_value'];
}
What I am missing here?
Thank you!
If sometimes, attribute_value can be an array, and inside it the values, you can just check inside the loop (Provided this is the max level) using is_array() function. Example:
$vMine = array();
foreach ($array as $k => $v) {
if(is_array($v['attribute_value'])) { // check if its an array
// if yes merge their contents
$vMine = array_merge($vMine, $v['attribute_value']);
} else {
$vMine[] = $v['attribute_value']; // if just a string, then just push it
}
}
I suggest you to use array_map instead of for loop. You can try something like this..
$vMine = array_map(function($v) {
return is_array($v['attribute_value']) ? current($v['attribute_value']) : $v['attribute_value'];
}, $arr);
print '<pre>';
print_r($vMine);
Try the shorthand version:
foreach ($array as $k => $v) {
$vMine[] = is_array($v['attribute_value']) ? current($v['attribute_value']):$v['attribute_value'];
}
or the longer easier to understand version, both is the same:
foreach ($array as $k => $v) {
if(is_array($v['attribute_value'])) {
$vMine[] = current($v['attribute_value']);
} else {
$vMine[] = $v['attribute_value'];
}
}

Categories