PHP: Sort array by exploded value - php

How can I sort an array by a value from an exploded string?
To make it a bit more clear, I have data stored in a textfile in the following format:
Value_1|Value_2|Value_3|Value_4|Value_5
Value_1|Value_2|Value_3|Value_4|Value_5
Value_1|Value_2|Value_3|Value_4|Value_5
...
I read the data using
$data_file = 'foo.txt';
$lines = file($data_file, FILE_IGNORE_NEW_LINES);
then explode each line and output the content (HTML stripped to keep it clean)
foreach ($lines as $line_num => $dataset) {
$dataset = explode('|', $dataset);
//echo exploded values + some HTML
}
However, before I output the data, I want to sort the array by Value_2 (which is always a number) from e.g. high to low. Do I have to set the keys of the array to Value_2 and then sort it? How can I do that? What would be the best solution here?
Thanks for your help!
This is the final, slightly modified snippet for everyone who's interested:
$data_file = 'foo.txt';
$lines = file($data_file, FILE_IGNORE_NEW_LINES);
function sort_data_array($a, $b){
$ex_a = explode('|', $a);
$ex_b = explode('|', $b);
if ($ex_a[1] == $ex_b[1]) {return 0;}
return ($ex_a[1] > $ex_b[1]) ? -1 : 1;
}
uasort($lines, 'sort_data_array');
$lines = array_values($lines);
foreach ($lines as $line_num => $dataset) {
//output
}

Use a custom sort function:
EG:
uasort ($lines, function($a , $b)) {
$ex_a = explode('|', $a);
$ex_b = explode('|', $b);
// change the < to > if they are in reverse...
return (strcmp($ex_a[1], $ex_b[1]) < 0 ? 1: -1);
}
print_r($lines);

Here is a method without a custom sort function.
This can be refactored if the number of columns is unknown.
<?php
$raw_records = 'Value_1|2|Value_3|Value_4|Value_5
Value_1|5|Value_3|Value_4|Value_5
Value_1|3|Value_3|Value_4|Value_5';
$records = array();
$lines = explode("\n", $raw_records);
foreach ($lines as $line_num => $dataset) {
$dataset = explode('|', $dataset);
$records[$dataset[1]][] = $dataset[0];
$records[$dataset[1]][] = $dataset[2];
$records[$dataset[1]][] = $dataset[3];
$records[$dataset[1]][] = $dataset[4];
}
ksort($records, SORT_NUMERIC);
echo '<pre>'; var_dump($records); echo '</pre>';
?>

Related

how to get value of key in php associative array by comparing key with a string to get value?

I have below small PHP script, I just need the value from the array if I provide key in $str.
$empid_array = array('CIP004 - Rinku Yadav', 'CIP005 - Shubham Sehgal');
$key = array();
$value = array();
$str = "CIP004";
foreach($empid_array as $code){
$str = preg_split("/\-/", $code);
array_push($key, $str[0]);
array_push($value, $str[1]);
}
$combined = array_combine($key, $value);
echo count($combined);
foreach($combined as $k => $v){
if($str == $k){
echo $v;
}
}
You could simplify your code considerably here. Step one, use array_walk to walk through the array and build the $combined array. Step two, there's no point in looping through the array, just access the value by the index:
$empid_array = ['CIP004 - Rinku Yadav', 'CIP005 - Shubham Sehgal'];
$str = "CIP004";
$combined = [];
// passing $combined by reference so we can modify it
array_walk($empid_array, function ($e) use (&$combined) {
list($id, $name) = explode(" - ", $e);
$combined[$id] = $name;
});
echo $combined[$str] ?? "Not found";

PHP filter links

i have this array
$array = array(
"http://www.mywebsite.com/eternal_link_1",
"http://www.mywebsite.com/eternal_link_2/",
"http://www.mywebsite.com/eternal_link_1/#",
"http://subdomain1.mywebwite.com",
"http://subdomain2.mywebwite.com/eternal_link",
"http://www.external-link.com"
);
$eternal_links = array();
$subdomain_links = array();
$external_links = array();
how i can filter $array and add the values to the 3 arrays above?
You can use strpos to find the correct string.
foreach($array as $item){
if(strpos($item, 'external') == TRUE){
array_push($external_links, $item);
}
// and go on..
}

How to create multidimensional PHP array from this string?

I have a string I would like to separate and make a multidimensional array out of. The string looks like this:
$string = "item-size:large,color:blue,material:cotton,item-size:medium,color:red,material:silk,";
Unfortunately, I have no control over how the string is put together, which is why I'm trying to make this array.
My goal is to make an array like this:
$item[1]['color'] // = blue
$item[2]['material'] // = silk
So, here's what I've done:
$item = array();
$i=0; // I know this is messy
$eachitem = explode("item-",$string);
array_shift($eachitem); // get rid of the first empty item
foreach ($eachitem as $values) {
$i++; // Again, very messy
$eachvalue = explode(",",$values);
array_pop($eachvalue); // get rid of the last comma before each new item
foreach ($eachvalue as $key => $value) {
$item[$i][$key] = $value;
}
}
I'm obviously lost with this... any suggestions?
You're mostly there. Just replace your inner foreach with
foreach ($eachvalue as $value) {
$properties = explode(':', $value);
$item[$i][$properties[0]] = $properties[1];
}
You're close, this is how I would do it:
$string = "item-size:large,color:blue,material:cotton,item-size:medium,color:red,material:silk,";
$substr = explode("item-", $string);
$items = array();
foreach ($substr as $string) {
$subitems = array();
$pairs = explode(",", $string);
foreach ($pairs as $pair) {
list($key, $value) = explode(":", $pair, 2);
$subitems[$key] = $value;
}
$items[] = $subitems;
}
var_dump($items);
Using list here is great :) Do note that you would need the extra count limiter in explode else you might lose data if there are more :.
$array = array();
$string = explode(',', $string);
foreach($string as $part):
$part = trim($part);
if(strlen($part) < 3) continue;
$part = explode(':', $part);
$array[$part[0]] = $part[1];
endforeach;
$string = "item-size:large,color:blue,material:cotton,item-size:medium,color:red,material:silk,";
$num_attr = 3;
$item = array();
$i=$x=0;
foreach(explode(',', trim($string,',')) as $attr)
{
list($key, $value) = explode(':', $attr);
$item[$x+=($i%$num_attr==0?1:0)][$key] = $value;
$i++;
}
Set the $num_attr to the number of item attributes in the string (this will allow adjustments in the future if they grow/shrink). The trim inside the foreach is removing ay "empty" data like the last comma (it will also remove a empty first comma if one ever shows up). The crazy looking $item[$x+=($i%$num_attr==0?1:0)] is taking the modulus of the counter / number of attributes which when it is 0 that means we are on a new product line so we add 1 to x which populates the item number index, if the modulus returns a number then we know we are on the same product so we add 0 which doesn't change the items index so that attribute is added on to the same item.

PHP array group by data values

This is my $data variable:
cv = 1,2,3,4,5:::cpt = 4,5 ...
Now I need some function, where I can add the number as param (number will be $data number value).
for example.
function getPermission($id) {
... return $something;
}
Then if I call the function like: echo getPermission(4); it'll print out the data 'keys' where the 4 will be inside, as a value.
So, to be clear:
if I call the function like this:
echo getPermission(4); output will be "cv" and "cpt".
but if I call it this way:
echo getPermission(1);
it'll only output "cv" because number (1) is located in the cv key.
Hope you guys understand, feel free to ask if something aren't clear enough.
$str = 'cv = 1,2,3,4,5:::cpt = 4,5';
$tmp = explode(':::', $str);
$data = array();
foreach ($tmp as $arr) {
$tokens = explode(' = ', $arr);
$data[$tokens[0]] = explode(',', $tokens[1]);
}
print_r(getPermission(4, $data));
print_r(getPermission(1, $data));
function getPermission($id, $data) {
$out = array();
foreach ($data as $key => $arr) {
if (in_array($id, $arr)) $out[] = $key;
}
return $out;
}

PHP explode array

I'm trying to get random values out of an array and then break them down further, here's the initial code:
$in = array('foo_1|bar_1', 'foo_2|bar_2','foo_3|bar_3','foo_4|bar_4','foo_5|bar_5' );
$rand = array_rand($in, 3);
$in[$rand[0]]; //foo_1|bar_1
$in[$rand[1]]; //foo_3|bar_3
$in[$rand[2]]; //foo_5|bar_5
What I want is same as above but with each 'foo' and 'bar' individually accessible via their own key, something like this:
$in[$rand[0]][0] //foo_1
$in[$rand[0]][1] //bar_1
$in[$rand[1]][0] //foo_3
$in[$rand[1]][1] //bar_3
$in[$rand[2]][0] //foo_5
$in[$rand[2]][1] //bar_5
I've tried exploding $rand via a foreach loop but I'm obviously making some n00b error:
foreach($rand as $r){
$result = explode("|", $r);
$array = $result;
}
You were close:
$array = array();
foreach ($in as $r)
$array[] = explode("|", $r);
Try this...
$in = array('foo_1|bar_1', 'foo_2|bar_2','foo_3|bar_3','foo_4|bar_4','foo_5|bar_5' );
foreach($in as &$r){
$r = explode("|", $r);
}
$rand = array_rand($in, 3);
That modifies $in "on the fly", so it contains the nested array structure you're looking for.
Now...
$in[$rand[0]][0] //foo_1
$in[$rand[0]][1] //bar_1
$in[$rand[1]][0] //foo_3
$in[$rand[1]][1] //bar_3
$in[$rand[2]][0] //foo_5
$in[$rand[2]][1] //bar_5
I think that's what you're looking for.
foreach($rand as $r){
$result = explode("|", $r);
array_push($array, $result);
}

Categories