Order array of strings based on a portion of each string - php

How can i order an array from this:
$unordered_array = array('11196311|3','17699636|13','11196111|0','156875|2','17699679|6','11196237|7','3464760|10');
To this
$ordered_array = array('11196111', '156875', '11196311', '17699679','11196237','3464760', '17699636');
The number after the "|" defines the position, and the array needs to be ordered from lower to higher, and remove the position number in the final array.

Why you don't try by yourself ? You take more writing your answer than doing it by yourself.
$array = array();
foreach($unordered_array as $value) {
$value = explode('|', $value);
$array [$value[1]]= $value[0];
}
ksort($array);
$ordered_array = array_values($array);
var_dump($ordered_array);

Related

Replace array value with more than one values

I have an array like this,
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
I want to find any value with an ">" and replace it with a range().
The result I want is,
array(
1,2,3,4,5,6,7,8,9,10,11,12, '13.1', '13.2', 14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
);
My understanding:
if any element of $array has '>' in it,
$separate = explode(">", $that_element);
$range_array = range($separate[0], $separate[1]); //makes an array of 4 to 12.
Now somehow replace '4>12' of with $range_array and get a result like above example.
May be I can find which element has '>' in it using foreach() and rebuild $array again using array_push() and multi level foreach. Looking for a more elegant solution.
You can even do it in a one-liner like this:
$array = array(1,2,3,'4>12','13.1','13.2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,#range(...array_slice(explode(">","$c>$c"),0,2)));},
[]
));
I avoid any if clause by using range() on the array_slice() array I get from exploding "$c>$c" (this will always at least give me a two-element array).
You can find a little demo here: https://rextester.com/DXPTD44420
Edit:
OK, if the array can also contain non-numeric values the strategy needs to be modified: Now I will check for the existence of the separator sign > and will then either merge some cells created by a range() call or simply put the non-numeric element into an array and merge that with the original array:
$array = array(1,2,3,'4>12','13.1','64+2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,strpos($c,'>')>0?range(...explode(">",$c)):[$c]);},
[]
));
See the updated demo here: https://rextester.com/BWBYF59990
It's easy to create an empty array and fill it while loop a source
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$res = [];
foreach($array as $x) {
$separate = explode(">", $x);
if(count($separate) !== 2) {
// No char '<' in the string or more than 1
$res[] = $x;
}
else {
$res = array_merge($res, range($separate[0], $separate[1]));
}
}
print_r($res);
range function will help you with this:
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$newArray = [];
foreach ($array as $item) {
if (strpos($item, '>') !== false) {
$newArray = array_merge($newArray, range(...explode('>', $item)));
} else {
$newArray[] = $item;
}
}
print_r($newArray);

Pass comma separated key string and get value of array according to key in PHP

I am trying to get value from array and pass only comma separated key string and get same output without. Is it possible without using foreach statement. Please suggest me.
<?php
$str = "1,2,3";
$array = array("1"=>"apple", "2"=>"banana", "3"=>"orange");
$keyarray = explode(",",$str);
$valArr = array();
foreach($keyarray as $key){
$valArr[] = $array[$key];
}
echo $valStr = implode(",", $valArr);
?>
Output : apple,banana,orange
Use array_intersect_key
$str = "1,2,3";
$array = array("1"=>"apple", "2"=>"banana", "3"=>"orange");
$keyarray = explode(",",$str);
echo implode(",", array_intersect_key($array, array_flip($keyarray)));
https://3v4l.org/gmcON
One liner:
echo implode(",", array_intersect_key($array, array_flip(explode(",",$str))));
A mess to read but a comment above can explain what it does.
It means you don't need the $keyarray
Suggestion : Use separate row for each value, to better operation. Although you have created right code to get from Comma sparate key to Value from array, but If you need it without any loop, PHP has some inbuilt functions like array_insersect , array_flip to same output
$str = "1,2";
$arr1 = ["1"=>"test1","2"=>"test2","3"=>"test3"];
$arr2 = explode(",",$str);
echo implode(", ",array_flip(array_intersect(array_flip($arr1),$arr2)));
Live demo
you can try using array_filter:
$str = "1,2,3";
$array = array("1"=>"apple", "2"=>"banana", "3"=>"orange");
$keyarray = explode(",",$str);
$filtered = array_filter($array, function($v,$k) use($keyarray){
return in_array($k, $keyarray);
},ARRAY_FILTER_USE_BOTH);
print_r($filtered);
OUTPUT
Array
(
[1] => apple
[2] => banana
[3] => orange
)
Another way could be using array_map():
echo $valStr = implode(",", array_map(function ($i) use ($array) { return $array[$i]; }, explode(",", $str)));
Read it from bottom to top:
echo $valStr = implode( // 3. glue values
",",
array_map( // 2. replace integers by fruits
function ($i) use ($array) {
return $array[$i];
},
explode(",", $str) // 1. Split values
)
);

PHP: Add multiple entries to array

I have a string and a value.
I am exploding the string which returns a few results to a list.
I want to add each of those items from the list to an array, with the same value assigned to each string.
Here is what I have so far:
$count = 3;
$amount = 2500;
$value = ceil ($amount / $count);
$string = "String1, String2, String3, ";
$strings = explode(", ", $string);
I want to run a foreach that puts $strings and $value into an array together.
Any pointers?
You can simply use:
$combo = array_fill_keys( $strings , $value );
// var_dump( $combo ); // to check you got it right.
This takes the values in your $strings array and uses them as the keys for the new $combo array, setting the same value for each key.

Remove all elements in an array after the first instance of an element that matches same alphabetic (ONLY) value

I need to remove all elements in the array that comes after the FIRST instance of an element that matches same string value before the dot. ie, not taking into consideration any values after the .
from
$array = ("ItemNew1.1", "Item2.0", "Item3Test.0", "Item2.2", "Item4.4", "Item2.5")
to
$array = ("ItemNew1.1", "Item2.0", "Item3Test.0", "Item4.4")
The code below creates a temp array to hold the values that are already in the array, it runs a foreach on the original array and if the value is not in the temporary array, it inserts it into a new array
$tempArray = array();
$newArray = array();
foreach($array as $value) {
list($item, ) = explode(".", $value);
$int = filter_var($item, FILTER_SANITIZE_NUMBER_INT);
if(!in_array($int, $tempArray)) {
$newArray[] = $value;
$tempArray[] = $int;
}
}
Now, $newArray is the array that you want.
DEMO

PHP match string in array, modify string and then create new array

I'm not sure how to better phrase my question, but here is my situation.
I have an array like the following:
$temp_array = array("111111-Name1-122874|876394|120972", "222222-Name2-122874|876394|120972", "333333-Name3-122874|876394|120972");
I need to loop through this array and try to match the first portion of each string in the array
e.g.
$id = "222222";
$rand_number = "999888";
if ($id match the first element in string) {
fetch this string
append "999888" to "122874|876394|120972"
insert this string back to array
}
So the resulting array becomes:
$temp_array = array("111111-Name1-122874|876394|120972", "222222-Name2-999888|122874|876394|120972", "333333-Name3-122874|876394|120972");
Sorry if my question appears confusing, but it really is pretty difficult for me to even grasp some of the required operations.
Thanks
Try this:
$temp_array = array("111111-Name1-122874|876394|120972", "222222-Name2-122874|876394|120972", "333333-Name3-122874|876394|120972");
$id = "222222";
$rand_number = "999888";
// Loop over each element of the array
// For each element, $i = the key, $arr = the value
foreach ($temp_array as $i => $arr){
// Get the first characters of the element up to the occurrence of a dash "-" ...
$num = substr($arr, 0, strpos($arr, '-'));
// ...and check if it is equal to $id...
if ($num == $id){
// ...if so, add $random_number to the back of the current array element
$temp_array[$i] .= '|' . $rand_number;
}
}
Output:
Array
(
[0] => 111111-Name1-122874|876394|120972
[1] => 222222-Name2-122874|876394|120972|999888
[2] => 333333-Name3-122874|876394|120972
)
See demo
Note: As Dagon pointed out in his comment, your question says appends, but your example shows the data being prepended. This method appends, but can be altered as necessary.
http://php.net/manual/en/control-structures.foreach.php
http://php.net/manual/en/function.substr.php
http://php.net/manual/en/function.strpos.php
You could also using some exploding in this case too:
$temp_array = array("111111-Name1-122874|876394|120972", "222222-Name2-122874|876394|120972", "333333-Name3-122874|876394|120972");
$id = "222222";
$rand_number = "999888";
foreach($temp_array as &$line) {
// ^ reference
$pieces = explode('|', $line); // explode pipes
$first = explode('-', array_shift($pieces)); // get the first part, explode by dash
if($first[0] == $id) { // if first part is equal to id
$first[2] = $rand_number; // replace the third part with random
$first = implode('-', $first); // glue them by dash again
$line = implode('|', array($first, implode('|',$pieces))); // put them and glue them back together again
}
}
echo '<pre>';
print_r($temp_array);
crude answer - its going to depend on the expected values of the initial ids. if they could be longer or shorter then explode on the hyphen instead of using substr
$temp_array = array("111111-Name1-122874|876394|120972","222222-Name2-122874|876394|120972","333333-Name3-122874|876394|120972");
$id = "222222";
$rand_number = "999888";
foreach($temp_array as $t){
if(substr(0,6,$t)==$id){
$new[] = $t.'|'.$rand_number;
}else{
$new[] = $t;
}
}
Another version using array_walk
$temp_array = array("111111-Name1-122874|876394|120972", "222222-Name2-122874|876394|120972", "333333-Name3-122874|876394|120972");
$id = "222222";
$rand_number = "999888";
$params = array('id'=>$id, 'rand_number'=>$rand_number);
array_walk($temp_array, function(&$value, $key, $param){
$parts = explode('-', $value); // Split parts with '-' so the first part is id
if ($parts[0] == $param['id']){
$parts[2]="{$param['rand_number']}|{$parts[2]}"; //prepend rand_number to last part
$value=implode('-',$parts); //combine the parts back
}
},$params);
print_r($temp_array);
If you just want to append The code becomes much shorter
$params = array('id'=>$id, 'rand_number'=>$rand_number);
array_walk($temp_array, function(&$value, $key, $param){
// here check if the first part of the result of explode is ID
// then append the rand_number to the value else append '' to it.
$value .= (explode('-', $value)[0] == $param['id'])? "|{$param['rand_number']}" : '';
},$params);
Edit: Comments added to code.

Categories