Search For a Key in an Array, Recursively

Javascript - Recursively looking for keys in array with empty values

An alternate approach is to write a more generic function to recursively test validity of object properties given a predicate to test with.

It's not difficult; to my mind it's often simpler than writing the specific function directly. And applying it to a specific case is also simple.

It might look like this:

const isValid = (pred) => (obj) =>  Object .values (obj) .every (    v => (v && typeof v == 'object') ? isValid (pred) (v) : pred (v)  )
const noEmptyProps = isValid (v => v !== '' && v != null)
const obj = [{mainContact: true, contactName: "", emailId: "abc@gmail.com", contactAddress: [{addressType: "", county: "U.K.", postCode: "MK7 6BZ", houseFlatNumber: 1}, {addressType: "def", county: "France", postCode: "123MKO", houseFlatNumber: "223"}], phoneDetails: [{notes: "", phoneNumber: "1234567899", countryCode: "44", priority: "1"}, {notes: "Lorem ipsum", phoneNumber: "1112223331", countryCode: "48", priority: "2"}]}]
console.log (noEmptyProps (obj))

Get keys from multidimensional array recursively

This seems to work for me:

function array_keys_recursive(array $arr) {
foreach($arr as $key => $value) {
$return[] = $key;
if(is_array($value)) $return = array_merge($return, array_keys_recursive($value));
}
return $return;
}

Basically identical to yours, which also works, by the way.

Recursively find elements in dictionary using an array in Python

This should be a bit easier:

keys = ["a", "1", "2"]
dictionary = {
"a":{
"1": {
"1": "Some text",
"2": "This is the text I want",
"3": "Even more"
},
"2": {
"1": "Some text",
"2": "More text"
}
},
"b": {
"1": "Here is some text",
"2": {
1: "Some text"
},
"3": {}
}
}

for key in keys: # drop to lower level of dictionary with each loop
try:
dictionary = dictionary[key]
except KeyError:
dictionary = 'ERROR'
break

print(dictionary) # after the loop ends, 'dictionary' will hold the required value

PHP: Returning from a recursive array searching function

public function recursiveArraySearch($needle, $haystack)
{
foreach ($haystack as $key => $value) {
if ($key === $needle) {
return $value;
} elseif (is_array($value)) {
$result = $this->recursiveArraySearch($needle, $value);
if ($result !== false){
return $result;
}
}
}

return false;
}

When you recurse down you need to check the result and return only if an item was found. If nothing was found then you need to let the loop continue.

This assumes that your array does not contain any boolean values. If it does, you'll need to use an alternate method to avoid confusing a false value for not found.

How to recursively go through an array of ojects with child arrays and return a final transformed array of objects

What about this:

// this function recurses down the tree and for each item it makes a
// transformed item (saving only the title and key). Then the transformed
// item is returned and the caller pushes it into the children array
function buildtree(obj) {
let item = {
title: obj.name || obj.title,
key: obj.id || obj.key,
children: []
}

if (obj.children)
for (child of obj.children)
item.children.push( buildtree(child) )

return item;
}

let result = [
{
title: 'Projects',
key: 'projects',
children: []
}
]

result[0].children.push( buildtree(obj) )

Here is a full runnable example:

obj = {
id: '1234',
name: 'item 1',
x: '', // other properties that I don't care about will be here too
children: [
{
id: '2345',
name: 'item 2',
x: '', // other properties that I don't care about will be here too
children: [
{
id: '3456',
name: 'item 3',
x: '', // other properties that I don't care about will be here too
children: [
{
id: '4567',
name: 'item 4',
x: '', // other properties that I don't care about will be here too
},
{
id: '5678',
name: 'item 5',
x: '', // other properties that I don't care about will be here too
}
]
},
{
id: '6789',
name: 'item 6',
x: '', // other properties that I don't care about will be here too
children: [
{
id: '7890',
name: 'item 7',
x: '', // other properties that I don't care about will be here too
},
{
id: '890a',
name: 'item 8',
x: '', // other properties that I don't care about will be here too
}
]
}
]
},
{
id: '90ab',
name: 'item 9',
x: '', // other properties that I don't care about will be here too
children: [
{
id: '0abc',
name: 'item 10',
x: '', // other properties that I don't care about will be here too
children: [
{
id: 'abcd',
name: 'item 11',
x: '', // other properties that I don't care about will be here too
},
{
id: 'bcde',
name: 'item 12',
x: '', // other properties that I don't care about will be here too
}
]
},
{
id: 'cdef',
name: 'item 13',
x: '', // other properties that I don't care about will be here too
children: [
{
id: 'defg',
name: 'item 14',
x: '', // other properties that I don't care about will be here too
},
{
id: 'efgh',
name: 'item 15',
x: '', // other properties that I don't care about will be here too
}
]
}
]
}
]
}

console.log( JSON.stringify(obj) )

function buildtree(obj) {
let item = {
title: obj.name || obj.title,
key: obj.id || obj.key,
children: []
}

if (obj.children)
for (child of obj.children)
item.children.push( buildtree(child) )

return item;
}

let result = [
{
title: 'Projects',
key: 'projects',
children: []
}
]
result[0].children.push( buildtree(obj) )

console.log( JSON.stringify(result) )

How to find the key of a value in a nested object recursively

After the few questions made above, it looks like the function should:

  • Assume the input is always an object.
  • Assume it might encounter arrays in its way.
  • Assume it must stop after meeting one value (in case multiple value exists).

The provided input code given by the OP does not handle array cases.

Below code is sampled to work with these sample cases:

  • Plain nested object structure.
  • Object with nested arrays of objects or elements.

Below function accepts a second argument which is a callback to evaluate whether the element met is actually the one we're looking for. In this way, it's easier to handle more complex checks.

The recursive approach is kept and, once the key is met, the function simply return to avoid unnecessary searchs.

const foo = { data: { data2: { data3: 'worked' }, data21: 'rand' }, data01: 'rand01' };const fooWithArrays = {  data: {    data2: {      data3: 'not here'    },    data4: [      { data5: 'worked' },      { data6: 'not me' }    ]  }};const fooWithExpression = {  data: {   data2: {    data3: { id: 15, name: 'find me!' }   },   data21: {    data25: 'not me'   }  }};
const findKeyByValue = (obj, equalsExpression) => { // Loop key->value pairs of the input object. for (var [key, v] of Object.entries(obj)) { // if the value is an array.. if (Array.isArray(v)) { // Loop the array. for (let i = 0; i < v.length; i++) { // check whether the recursive call returns a result for the nested element. let res = findKeyByValue(v[i], equalsExpression); // if so, the key was returned. Simply return. if (res !== null && res !== undefined) return res; } } // otherwise.. else { // if the value is not null and not undefined. if (v !== null && v !== undefined) { // if the value is an object (typeof(null) would give object, hence the above if). if (typeof(v) === 'object') { // check whether the value searched is an object and the match is met. if (equalsExpression(v)) return key; // if not, recursively keep searching in the object. let res = findKeyByValue(v, equalsExpression); // if the key is found, return it. if (res !== null && res !== undefined) return res; } else { // finally, value must be a primitive or something similar. Compare. let res = equalsExpression(v); // if the condition is met, return the key. if (res) return key; // else.. continue. } } else continue; } }}
console.log( findKeyByValue(foo, (found) => found === 'worked') );console.log( findKeyByValue(fooWithArrays, (found) => found === 'worked') );console.log( findKeyByValue(fooWithExpression, (found) => found && found.id && found.id === 15) );

Recursive search and remove in array?

You can ease things by only using references.

function removeKey($key, &$array, $childKey = 'children'){
if(isset($array[$key])){
unset($array[$key]);
return;
}

foreach($array as &$item)
if(isset($item[$childKey]))
removeKey($key, $item[$childKey], $childKey);
}

Example:

$arr = array(...);
removeKey('key', $arr, $chilKey);
// Just continue using $arr

Search recursively for value in object by property name

You could use Object.keys and iterate with Array#some.