array_search Recursive in javascript
-
06-07-2021 - |
Pregunta
function array_searchRecursive( $needle, $haystack, $strict=false, $path=array() )
{
if( !is_array($haystack) ) {
return false;
}
foreach( $haystack as $key => $val ) {
if( is_array($val) && $subPath = array_searchRecursive($needle, $val, $strict, $path) ) {
$path = array_merge($path, array($key), $subPath);
return $path;
} else if( (!$strict && $val == $needle) || ($strict && $val === $needle) ) {
$path[] = $key;
return $path;
}
}
return false;
}
Do any body suggest me the same funcitonality, that can be implemented in javascript. reference http://www.php.net/manual/en/function.array-search.php#68424
Solución
This might give you a start. Not thoroughly tested or highly optimized, and assumes use of jQuery (shouldn't be a big problem to replace the jQuery utilty functions with other implementations).
function searchArrayRecursive(needle, haystack, strict) {
function constructPath(needle, haystack, path, strict) {
if (!$.isArray(haystack)) {
return false;
}
var index;
for (index = 0; index < haystack.length; index++) {
var value = haystack[index];
var currentPath = $.merge([], path);
currentPath.push(index);
if ((strict && value === needle) || (!strict && value == needle)) {
return currentPath;
}
if ($.isArray(value)) {
var foundPath = constructPath(needle, value, currentPath, strict);
if (foundPath) {
return foundPath;
}
}
}
return false;
}
return constructPath(needle, haystack, [], strict);
}
Otros consejos
Indeed underscore (or probably better performing: lodash) is your man. JavaScript is for a huge part a functional language and in the latest spec contains most features that underscore provides. For browser-compat underscore is still adviced.
The best underscore feature in your situation is:
var haystack = [
{a: 1}, [{b: 2}, {c: 3}, [{d: 4}, {e: 5}, [{f: 6}, {g: 7}] ] ]
],
needle = 4;
//Search
var result = _(haystack).chain() //chain so we can keep underscoring
.flatten() //flatten the array
.find(function(o) { //find the first element that matches our search function
return _(o).chain() //chain so we can keep underscoring
.values() //get all object values as an array
.contains(needle) //see if any of our values contains the needle
.value(); //get out of the chain
})
.value(); //get out of the chain
//In short:
var result = _(haystack).chain().flatten().find(function(o) { return _(o).chain().values().contains(needle).value(); }).value();
Of course you will have to fine-tune this and implement your $strict and whatsoever.
If you are open to using libraries, I think Underscore.js has functionality that will get you what you're looking for, using possibly _.find(), _.pluck(), or _.pick(). There are plenty of other methods that can help with this.
If you want to do it in core JS, have a peek under the covers of Underscore source code, which has FANTASTIC annotations / documentation: