Comments (12)
Ok, let's wait several months till the few people who haven't already searched for a less verbose way to build associative arrays in PHP start upvoting this coming via Google, if you don't think this suggestion is useful.
from functional-php.
create_assoc
? Anw, what might be a use case for this?
from functional-php.
@phanan Sorry, I messed up explaining what I want.
Basically what I suggest is an analogue to Yii2's ArrayHelpers::map
. It doesn't do what map
does in functional programming (i.e. taking a list and returning another list), but rather it takes:
- an input list
- a function to produce keys of the output list
- a function to produce values of the output list
and creates an associative array (a map) from the keys to values for the same elements of the original array, e.g.:
ArrayMap::map(
[
['id' => 1, 'name' => 'Bob'],
['id' => 2, 'name' => 'Joj'],
['id' => 3, 'name' => 'Yoy'],
],
function($elem, $index) {
return $elem['id'];
},
function($elem, $index) {
return 'Mister '.$elem['name'];
}
);
/*
returns
[
1 => 'Mister Bob',
2 => 'Mister Joj',
3 => 'Mister Yoy'
]
*/
Example: I have a list of books. I need to get a map from book ids to their names to pass to a view to render a <select>
element
In plain PHP:
$ids2Names = [];
foreach ($books as $book) {
$ids2Names[$book->id] = $book->name;
}
With ArrayHelper::map
from Yii2:
ArrayHelper::map(
$books,
function($book) { return $book->id; },
function($book) { return $book->name; }
);
With create_assoc
:
create_assoc(
$books,
function($book) { return $book->id; },
function($book) { return $book->name; }
);
Benefit of this approach in comparison to plain php is that it is more semantical and isolates logic for getting keys and values, doesn't require you to come up with the assotiative array name. We can also add a check that no two entries of the input array produce the same key.
from functional-php.
@phanan Also create_asoc
can be useful for print debugging in some cases. But most importantly it can be useful in formatting input data in an MVC view.
from functional-php.
array_combine(map(…, …), map(…, …))
is not good enough?
from functional-php.
array_combine(
map($books, function($book) {
return $book->id;
}),
map($books, function($book) {
return $book->name;
})
);
vs
create_assoc(
$books,
function($book) { return $book->id; },
function($book) { return $book->name; }
);
Also if we want to do something like this:
create_assoc(
filter(
$bookRepository->getBooks(),
function() {
// maybe some more logic
}
),
function($book) { return $book->id; },
function($book) { return $book->name; }
);
then in the array_combine()
case we'll have to use an extra variable.
Also map
and the input array are not written twice in create_assoc
. Also using create_assoc
would explicitly state the relation between keys and values, unlike array_combine
where you'd have to parse it visually. I think functional-php has many functions that are much more niche than this one, and ability to create associative arrays easily to me seems to be an essential but missing piece of this library ($preserveKeys
everywhere).
from functional-php.
Personally, I don't see a big gain :/ Btw, your create_assoc
's example should have been written this way for a fairer comparison:
create_assoc(
$books,
function($book) {
return $book->id;
},
function($book) {
return $book->name;
}
);
As you can see, create_assoc
is one LoC longer ;)
from functional-php.
@phanan It is not about LoC, it is about the amount of nested expressions ;;;)))
Btw, if you rewrite my create_assoc
example, then consider doing the same for array_combine
:
array_combine(
map(
$books,
function($book) {
return $book->id;
}
),
map(
$books,
function($book) {
return $book->name;
}
)
);
from functional-php.
Another option that came to mind was to use reindex:
map(
function ($book) { return $book->name; },
reindex(
function($book) { return $book->id; },
filter($collection, …)
)
)
But I like that the create_assoc
reads so well. Let me ponder this a bit longer
from functional-php.
What do you think about unfold?
https://github.com/apantle/fun-php/blob/master/README.md#unfold
It does already what you are looking for, if the passed function is unary is called with just the input as argument, and allows optional values or even a helper to pass around values between applied functions.
We use it to apply a bunch of different service calls to a single entry, like a tap but calling many functions to build a single assoc array.
Happy to merge this little function of mine with more tests and a better suited name to the project.
from functional-php.
So @gvlasov, my proposal it very similar to what you have requested, but instead of directly building the associative array, instead I'm returning a function that allow to build any number of associative arrays, based on the same set of rules with a single or a series of input values.
If there are some issues on my proposal, please let me know to make it more useful. My tests are copied from the independent project I've worked this function, and they are thought more closely to a complement of another library that I use to map associative arrays, reducing them being a common case. This function makes the opposite, that's why in the little collection I've built I called it originally unfold
.
from functional-php.
Hi,
Is this what you're looking for?
from functional-php.
Related Issues (20)
- Flatten array performance HOT 6
- PHP 7? HOT 3
- functional shortcut for array_reduce? HOT 1
- Write docs for converge()
- Porper file comment instead of full license text HOT 1
- The opposite of `select_keys` HOT 2
- Support psalm HOT 10
- Let the default callback argument to function some, none, and every be the identity function HOT 4
- Support .phpstorm.meta
- pick should use array_key_exists instead of isset HOT 3
- Make these functions more expressive HOT 3
- Functions can no longer be called `match` on PHP 8
- [BUG] 1.14.0 breaks when opcache.preload is enabled HOT 1
- PHP 8 Support HOT 3
- Proposal: Add compact() HOT 3
- When will the php v8 be supported? HOT 3
- Use php-quickcheck for testing
- `take_left(sequence_linear(date('Y') - 3, 1), 3)` infinite loop
- Add iterable to the method definitions
- Tail Recursion does not work HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from functional-php.