I'm trying to unset two specific array positions which contain two values.
My actual code to fill the array.
function get_store_list(){
$data = #file_get_contents('http://www.zwinky.com/xml/clothingList.xml');
$data = #simplexml_load_string($data);
$data = $data->xpath('//stores/store');
foreach($data as $store) {
$storeArray[] = array(
"name" => (string)$store['name'],
"id" => (string)$store['id']
);
}
return $storeArray;
}
$store = get_store_list();
The array looks like the following incase ill echo it out using print_r function:
Array
(
[0] => Array
(
[name] => Artizans
[id] => 20037336
)
[1] => Array
(
[name] => Bwabies!
[id] => 20080134
)
[2] => Array
(
[name] => Crave Mart
[id] => 20097365
)
[3] => Array
(
[name] => David & Goliath
[id] => 20099998
)
[4] => Array
(
[name] => Domo
[id] => 20098166
)
[5] => Array
(
[name] => Emily the Strange
[id] => 20101926
)
[6] => Array
(
[name] => Garfield
[id] => 20098167
)
[7] => Array
(
[name] => Jetsetter
[id] => 26
)
[8] => Array
(
[name] => Like Dat
[id] => 3
)
[9] => Array
(
[name] => Paris Hilton
[id] => 21
)
[10] => Array
(
[name] => Peppermint Place
[id] => 12
)
[11] => Array
(
[name] => Rocawear
[id] => 19
)
[12] => Array
(
[name] => ShoeBuy
[id] => 10
)
[13] => Array
(
[name] => Skelanimals
[id] => 20100198
)
[14] => Array
(
[name] => Snoop Dogg
[id] => 20
)
[15] => Array
(
[name] => SW&TH
[id] => 20096121
)
[16] => Array
(
[name] => The Castle
[id] => 1
)
[17] => Array
(
[name] => The Lair
[id] => 4
)
[18] => Array
(
[name] => The Mix
[id] => 923
)
[19] => Array
(
[name] => The Powerpuff Girls
[id] => 20098121
)
[20] => Array
(
[name] => The Surf Shop
[id] => 5
)
[21] => Array
(
[name] => Tie The Knot
[id] => 20076231
)
[22] => Array
(
[name] => tokidoki
[id] => 20099224
)
[23] => Array
(
[name] => University Club
[id] => 2
)
[24] => Array
(
[name] => Z Avenue
[id] => 6
)
[25] => Array
(
[name] => Z's Greetings
[id] => 20099506
)
)
Now $store does contain 2 array indexes which I have to delete. Which are the following ids: 21 and 20076231
I've been trying the following already:
Array search code without beeing success. Does anyone have a idea what I could try?
There are a handful different approaches for this simple issue. One of them could be using function array_filter():
/**
* #param array $list the list to process
* #param array $IDsToRemove the IDs of elements to remove from $list
* #return array a subset of $list that does not contain elements having 'id' in $IDsToRemove
*/
function removeFromArray(array $list, array $IDsToRemove)
{
return array_filter(
// Filter the input list...
$list,
// ... using a function...
function (array $item) use ($IDsToRemove) {
// ... that accepts an element if its "id" is not in $IDsToRemove
return ! in_array($item['id'], $IDsToRemove);
}
);
}
// Usage
$filteredStore = removeFromArray($store, array(21, 20076231));
Try this in your loop, this will not include in your array than no need to unset like this:
foreach($data as $store) {
if($store['id'] == '20076231')
continue;
$storeArray[] = array(
"name" => (string)$store['name'],
"id" => (string)$store['id']
);
}
If you need to unset an item from your array after it's been created, take a look at array_map.
First map your array to retrieve the index of each ID.
$map = array_map(function($item){ return $item['id']; }, $store);
Then get the index of your ID from the map (e.g. 21).
$index = array_search(21, $map);
Then remove with array_splice.
array_splice($store, $index, 1);
why not use directly the id in your $storeArray? And as it seems to be integer why do you force it to (string)?
Try this:
function get_store_list(){
$data = #file_get_contents('http://www.zwinky.com/xml/clothingList.xml');
$data = #simplexml_load_string($data);
$data = $data->xpath('//stores/store');
foreach($data as $store) {
$storeArray[(int)$store['id']] = array(
"name" => (string)$store['name']
);
}
return $storeArray;
}
// delete the keys you want
unset ($storeArray[21], $storeArray[20076231]);
// or if you have more ids to delete you can create a deleteArray
$deleteArray = array(2, 20076231);
foreach ($deleteArray as $toDelete){
unset($storeArray($toDelete);
}
One line code is cool but sometimes explicit code is preferable.
function filter_by_id(array $data, $id)
{
foreach ($data as $k => &$v) {
foreach ((array) $id as $i) {
if ($v['id'] === $i) {
$v = null;
}
}
}
// 'array_filter()' produces a new array without the null entries.
// 'array_values()' produces a new array with indexes without gaps.
return array_values(array_filter($data));
}
You can filter by one id at time
$store = filter_by_id($store, 21);
Or you can filter multiple ids at the same time:
$store = filter_by_id($store, [21, 20076231]);
Related
I have three arrays first array include ids and employees name and second array have monthly collection with employee ids and third array have daily collection with employee id and daily collection I want to merge these array with ids and name and dcollection and monthly collection but the desired output is not coming here my first array $ids is
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => Rohit
)
[1] => stdClass Object
(
[id] => 2
[name] => Emop1
)
[2] => stdClass Object
(
[id] => 3
[name] => Pankaj
)
[3] => stdClass Object
(
[id] => 4
[name] => tejpal singh
)
)
second array $q1 is
Array
(
[0] => stdClass Object
(
[name] => Rohit
[id] => 1
[mcollecton] => 100
)
[1] => stdClass Object
(
[name] => Emop1
[id] => 2
[mcollecton] => 1222
)
)
third array $q2 is
Array
(
[0] => stdClass Object
(
[name] => Rohit
[id] => 1
[dcollecton] => 300
)
[1] => stdClass Object
(
[name] => Emop1
[id] => 2
[dcollecton] => 150
)
)
so far what I have tried
$new_array = array();
foreach($ids as $k) {
$q1n = array("id"=>$k->id,"name"=>$k->name);
foreach($q1 as $k1) {
if($k->id==$k1->id){
$mc = array("mc"=>$k1->mcollecton);
array_merge($q1n,$mc);
}
}
foreach($q2 as $k1){
if($k->id==$k1->id){
$dc = array("dc"=>$k1->dcollecton);
array_merge($q1n,$dc);
}
}
$a = array_merge($q1n,$mc);
$av = array_merge($q1n,$dc);
array_push($new_array,$q1n);
}
but the output is coming as
Array
(
[0] => Array
(
[id] => 1
[name] => Rohit
)
[1] => Array
(
[id] => 2
[name] => Emop1
)
[2] => Array
(
[id] => 3
[name] => Pankaj
)
[3] => Array
(
[id] => 4
[name] => tejpal singh
)
)
I want the output be like
Array
(
[0] => Array
(
[id] => 1
[name] => Rohit
[mcollection] => 100
[dcollection] => 300
)
[1] => Array
(
[id] => 2
[name] => Emop1
[mcollection] => 1222
[dcollection] => 150
)
[2] => Array
(
[id] => 3
[name] => Pankaj
[mcollection] => 0
[dcollection] => 0
)
[3] => Array
(
[id] => 4
[name] => tejpal singh
[mcollection] => 0
[dcollection] => 0
)
)
So I have tried many times but the desired output is not coming . please help me out how to get the desired output.
It seemed like that answer could be modified, or put in a function that you could call multiple times if needed to combine more than two arrays.
There's probably cleaner ways to handle this with array functions like array_merge or array_walk, but this is the general idea of how I might approach it. I haven't tested this, but maybe it's useful.
foreach($first as $key1 => $value){
foreach($second as $key2 => $value2){
// match the ids and check if array key exists on first array
if($value['id'] === $value2['id'] && empty($first[$key2])){
$first[$key][$key2] = $value2;
}
}
}
EDIT: Based on the answer you posted vs the question you asked, are you incrementing the collection numbers or just setting them? In other words why use +=? You should also be able to remove array_merge and array_push.
Below is geared more towards what you're trying to do. I haven't tested this either, but if you run into errors, post your code with the errors returned so that it's easier to debug:
foreach($ids as $k)
{
$thisArray = $newArray[] = array("id"=>$k->id,"name"=>$k->name);
foreach($q1 as $k1)
{
if($k->id == $k1->id && !empty($k1->mcollecton))
{
$thisArray['mc'] = $k1->mcollecton;
}
}
foreach($q2 as $k2)
{
if($k->id == $k2->id && !empty($k2->dcollecton))
{
$thisArray['dc'] = $k2->dcollecton;
}
}
}
// This should have both new collections fields on all array items
print_r($newArray)
data
Array
(
[0] => Array
(
[id] => 9962
[value] => Amart
)
[1] => Array
(
[id] => attrval_9962
[value] => k
)
[2] => Array
(
[id] => 9952
[value] => Denim
)
[3] => Array
(
[id] => attrval_9952
[value] => l
)
[4] => Array
(
[id] => 5788
[value] => Grey
)
[5] => Array
(
[id] => 21307
[value] => Long Sleeve
)
)
Above is the data that store in array, anyone know how to unset the data if the attrval_ exist so that i want to unset the data id 9962. so the data will look like below.
Array
(
[0] => Array
(
[id] => attrval_9962
[value] => k
)
[1] => Array
(
[id] => attrval_9952
[value] => l
)
[2] => Array
(
[id] => 5788
[value] => Grey
)
[3] => Array
(
[id] => 21307
[value] => Long Sleeve
)
)
Which mean that I only want to store the data which is attrval_ exists else will store back the default value.
First get an Array which contain
$filtered = array_filter($data, function($element){
return strpos($element['id'], 'attrval_') !== false;
});
Then find the difference of both array.
$result = array_udiff($data, $filtered, function($a, $b) {
return intval($a != $b);
});
You can do it with
$result = [];
foreach(data as $value){
if(strpos($value['id'],'attrval_) !== false){
$result[] = $value
}
}
$filtered = array_filter($array, function ($data) {
return strpos($data['id'], 'attrval_') !== false;
});
I've this piece of code in which I want to know is there anyway I could avoid pass by reference
public function formatNumbers($numbersData){
$result = array();
array_map(
function($row) use (&$result) {
$result[$row['GroupId']][$row['Type']] = $row['value'];
}, $numbersData
);
return $result;
}
Input: $numbersData =
Array
(
[0] => Array
(
[GroupId] => 2
[Type] => 1
[value] => 82000
)
[1] => Array
(
[GroupId] => 2
[Type] => 3
[value] => 52000
)
[2] => Array
(
[GroupId] => 2
[Type] => 4
[value] => 30105
)
[3] => Array
(
[GroupId] => 2
[Type] => 7
[value] => 13266
)
)
Output is
Array
(
[2] => Array
(
[1] => 82000
[3] => 52000
[4] => 30105
[7] => 13266
)
)
I know I can do it using foreach, but I want to know that if there anyway to use array map for this without pass by reference.Any help would be greatly appreciated.
Wrong kind of operation. You're not looking for a mapping of values, you're looking for an array reduction:
return array_reduce($numbersData, function(array $acc, array $row) {
$acc[$row['GroupId']][$row['Type']] = $row['value'];
return $acc;
}, []);
You can do it using array_column() function.
$arr = array(array('GroupId'=>2,'Type' => 1,'value' => 82000),array('GroupId'=>2,'Type' => 3,'value' => 52000),array('GroupId'=>2,'Type' => 4,'value' => 30105),array('GroupId'=>2,'Type' => 7,'value' => 13266));
print_r(array_column($arr, 'value', 'Type'));
This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 8 years ago.
I've trawled a lot of questions and php manual, but I can't find a way to get sort this data in a graceful way. There may not be, but I'll settle for non-graceful.
At the moment I have a page that builds 4 arrays with data from post. The number of keys changes depending on the input;
// Grab the Tasks
$arraytask = $_POST["task"];
// Grab the Relusers
$arrayreluser = $_POST["reluser"];
// Grab the Usernames
$arrayuser = $_POST["user"];
// Grab the License Types
$arraylicense = $_POST["license"];
$result = array();
foreach( $arraytask as $key => $val) {
$result[] = array('key'=>$key, 'value'=>$val);
}
foreach( $arrayreluser as $key => $val) {
$result[] = array('key'=>$key, 'value'=>$val);
}
foreach( $arrayuser as $key => $val) {
$result[] = array('key'=>$key, 'value'=>$val);
}
foreach( $arraylicense as $key => $val) {
$result[] = array('key'=>$key, 'value'=>$val);
}
ksort($result); // I know this does nothing, I was hoping it would recursively sort or something
At the moment, the output on an example submission looks like (and sorry for the long formatting):
print_r($result);
Array (
[0] => Array (
[key] => 0
[value] => 123 )
[1] => Array (
[key] => 1
[value] => 456 )
[2] => Array (
[key] => 2
[value] => 789 )
[3] => Array (
[key] => 0
[value] => qwe )
[4] => Array (
[key] => 1
[value] => rty )
[5] => Array (
[key] => 2
[value] => uio )
[6] => Array (
[key] => 0
[value] => asd )
[7] => Array (
[key] => 1
[value] => fgh )
[8] => Array (
[key] => 2
[value] => jkl )
[9] => Array (
[key] => 0
[value] => license 1 )
[10] => Array (
[key] => 1
[value] => license 2 )
[11] => Array (
[key] => 2
[value] => license 3 )
)
However I want the output to be like
print_r($result);
Array (
[0] => Array (
[key] => 0
[value] => 123 )
[3] => Array (
[key] => 0
[value] => qwe )
[6] => Array (
[key] => 0
[value] => asd )
[9] => Array (
[key] => 0
[value] => license 1 )
[1] => Array (
[key] => 1
[value] => 456 )
[4] => Array (
[key] => 1
[value] => rty )
[7] => Array (
[key] => 1
[value] => fgh )
[10] => Array (
[key] => 1
[value] => license 2 )
[2] => Array (
[key] => 2
[value] => 789 )
[5] => Array (
[key] => 2
[value] => uio )
[8] => Array (
[key] => 2
[value] => jkl )
[11] => Array (
[key] => 2
[value] => license 3 )
)
I know I'm sorting Arrays by their keys... I just can't think of a better way to sort this data.
At the moment I've looked at array_merge() which seems to overwrite duplicate keys, and I've tried a few variations of foreach loops which have just ended in tears for everyone involved.
An alternative way to ask this question would be "If I can't sort these arrays by the keys within them, can I merge my 4 arrays so that the values of each array compile in to a single array, based off key?"
An acceptable (seemingly more graceful) output would also be
Array (
[0] => Array (
[key] => 0
[value] => 123, qwe, asd, license 1 )
[1] => Array (
[key] => 1
[value] => 456, rty, fgh, license 2 )
[2] => Array (
[key] => 2
[value] => 789, uio, jkl, license 3 )
)
I'm just not sure I can append values to keys in an array, if I do not explicitly know how many keys there are.
Postscript: if there are typos here, that's because this is the example cut down from the actual code for clarity, and I'm sorry. My issue isn't typos.
::SOLUTION::
Thanks to vstm, this worked for combining multiple arrays into a more useful array data;
$result = array();
foreach($arraytask as $key => $val) {
$result[] = array(
'key' => $key,
'task' => $arraytask[$key],
'reluser' => $arrayreluser[$key],
'user' => $arrayuser[$key],
'license' => $arraylicense[$key],
'value' => implode(', ', array(
$arraytask[$key],
$arrayreluser[$key],
$arrayuser[$key],
$arraylicense[$key],
))
);
}
Shows the output as
Array (
[0] => Array (
[key] => 0
[task] => 123
[reluser] => qwe
[user] => asd
[license] => license 1
[value] => 123, qwe, asd, license 1 )
[1] => Array (
[key] => 1
[task] => 456
[reluser] => rty
[user] => fgh
[license] => license 2
[value] => 456, rty, fgh, license 2 ) )
Well it seems that your input data is already given in a way that would make sorting useless. Try it this way:
// Grab the Tasks
$arraytask = $_POST["task"];
// Grab the Relusers
$arrayreluser = $_POST["reluser"];
// Grab the Usernames
$arrayuser = $_POST["user"];
// Grab the License Types
$arraylicense = $_POST["license"];
$result = array();
foreach($arraytask as $key => $val) {
$result[] = array(
'key' => $key,
'task' => $arraytask[$key],
'reluser' => $arrayreluser[$key],
'user' => $arrayuser[$key],
'license' => $arraylicense[$key],
'value' => implode(', ', array(
$arraytask[$key],
$arrayreluser[$key],
$arrayuser[$key],
$arraylicense[$key],
))
);
}
Now you have your "seemingly graceful" output, plus access to all the fields which you might need for working with your data. No need for sorting.
Try by usort(). Example here...
function sortByValue($a, $b) {
return $a['key'] - $b['key'];
}
usort($arr, 'sortByValue');
print '<pre>';
print_r($arr);
I have table name 'preferences' column(key,value)
I use cache in codeigniter
look this :
$pref = $this->ci->db->get('preferences')->result();
$this->ci->cache->save('preferences', $pref, 30000);
save cache :
a:3:{s:4:"time";i:1386246188;s:3:"ttl";i:30000;s:4:"data";a:87:{i:0;O:8:"stdClass":2:{s:3:"key";s:10:"site_title";s:5:"value";s:13:"CARS Big";}i:1;O:8:"stdClass":2:{s:3:"key";s:11:"forum_title";s:5:"value";s:14:"CARS Big forum";}i:2;O:8:"stdClass":2:{s:3:"key";s:14:"forum_per_page";s:5:"value";s:2:"10";}...
Call cache use:
$data = $this->ci->cache->get('preferences');
print_r($data);
output:
Array(
[0] => Array
(
[key] => site_title
[value] => CARS Big
)
[1] => Array
(
[key] => forum_title
[value] => CARS Big forum
)
[2] => Array
(
[key] => forum_per_page
[value] => 10
)
[3] => Array
(
[key] => forum_section_per_page
[value] => 10
)
[4] => Array
(
[key] => forum_replies_per_page
[value] => 5
)
[5] => Array
(
[key] => forum_can_add_pictures
[value] => 1
)
[6] => Array
(
[key] => forum_can_add_poll
[value] => 1
)
[7] => Array
(
[key] => forum_can_set_time_to_close
[value] => 1
)
[8] => Array
(
[key] => forum_can_set_replies_to_close
[value] => 1
)
[9] => Array
(
[key] => forum_auto_active_topics
[value] => 1
)
[10] => Array
(
[key] => market_title
[value] => market CARS Big
)
[11] => Array
(
[key] => market_per_page
[value] => 5
)
[12] => Array
(
[key] => market_section_per_page
[value] => 3
)
)
How do I make the content of the column key is the key
And the column value is the content
Like this:
$data['site_title']
I need $data['site_title'] to print : CARS Big
so as to call this function
function pref($key=NULL)
{
$data = $this->ci->cache->get('preferences');
return $data[$key];
}
**
Essentially you are looking to loop the values and re-assign the keys so something like this could work:
// loop through data
foreach($data as $k=>$v)
{
// unset the original array item to get rid of $data[0], $data[1], $data[2] as so forth
unset($data[$k]);
// $k is a digit (0,1,2,3,4,5,....)
// $v is the array of values so $v['key'] is 'site_title' and $v['value'] is 'CARS Big'
// so essentially we are doing $data['site_title'] = 'CARS Big'; in the line below
$data[$v['key']] = $v['value'];
}
you can't, since the cache save implementation is a fixed process. only if you make your own cache implementation.
but you can perform your return function like this
function pref($key=NULL)
{
// call pref data
$data = $this->ci->cache->get('preferences');
if( ! $data ) {
// cache not present request new
$data = $this->ci->db->get('preferences')->result();
$this->ci->cache->save('preferences', $data, 30000);
}
// loop
foreach( $data as $preferences ) {
if( isset( $preferences['key'] ) && $preferences['key'] == $key ){
return $preferences['value'];
}
}
return false;
}