Nested array. Third level is disappearing
To solve your problem you need to properly understand how variable referencing/aliasing in PHP works.
Look at the following example code, which does not look much different to yours but makes use of references in order to access any parent even it has already "moved":
# transform $flat into a tree:
foreach($flat as $id => &$value)
{
# check if there is a parent
if ($parentId = $value['parent'])
{
$flat[$parentId][0][$id] =& $value; # add child to parent
unset($flat[$id]); # remove reference from topmost level
}
}
unset($value); # remove iterator reference
print_r($flat); # your tree
$flat
now contains all values from $flat
- but reordered. Demo.
Nested array. Third level is disappearing
To solve your problem you need to properly understand how variable referencing/aliasing in PHP works.
Look at the following example code, which does not look much different to yours but makes use of references in order to access any parent even it has already "moved":
# transform $flat into a tree:
foreach($flat as $id => &$value)
{
# check if there is a parent
if ($parentId = $value['parent'])
{
$flat[$parentId][0][$id] =& $value; # add child to parent
unset($flat[$id]); # remove reference from topmost level
}
}
unset($value); # remove iterator reference
print_r($flat); # your tree
$flat
now contains all values from $flat
- but reordered. Demo.
From php multidimensional array trying to create nested ul li menu (unlimited nested levels)
Here's a summary of what it does:
- flatten the array recursively
- build a multi-dimensional relation map
- create 1D relationships that link UpperLevelNumberRenamed to NumberRenamed
- print out the multi-dimensional as an ul-li list.
Here it is:
$flat = array();
foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($main_topics)) as $i)
$flat[] = $i;
$final = array();
$defs = array();
for ($i = 0; $i < count($flat); $i += 3)
if ($flat[$i + 2] == 0) {
$final[$flat[$i + 1]] = array();
$defs[$flat[$i]] = &$final[$flat[$i + 1]];
} else {
$defs[$flat[$i + 2]][$flat[$i + 1]] = array();
$defs[$flat[$i]] = &$defs[$flat[$i + 2]][$flat[$i + 1]];
}
function array2ul($array) {
$out = "<ul>";
foreach($array as $key => $elem)
$out = is_array($elem) ?
$out . "<li><span>$key</span>" . array2ul($elem) . "</li>" :
$out = $out."<li><span>$key:[$elem]</span></li>";
$out = $out . "</ul>";
return $out;
}
echo array2ul($final);
Output:
<ul><li><span>Products</span><ul><li><span>Computers</span><ul><li><span>Laptops</span><ul><li><span>Dell</span><ul></ul></li><li><span>Acer</span><ul></ul></li></ul></li><li><span>Desktops</span><ul></ul></li></ul></li></ul></li><li><span>Home</span><ul></ul></li></ul>
How to Show/Hide nested array element/component after mapping outer array with useState in React?
My goal is to add an info/description object to each of the components
in the array so that when a component is toggled, the other components
still disappear but now a description shows up in accordance with the
toggled component.
You dont really mean disappear do you? sounds more like you want to conditionally render the component.
UPDATED
I misunderstood your intentions! Now they disappear.
// hooks
const {useState} = React;
function Comp1(){
return <div><p>Component 1</p></div>
}
function Comp2(){
return <div><p>Component 2</p></div>
}
function Comp3(){
return <div><p>Component 3</p></div>
}
function Comp4(){
return <div><p>Component 4</p></div>
}
const array = [
{ id: 1, component: <Comp1/>, isVisible: true,
info: { id: 5, component: <div>info1</div>, isVisibleInfo: false } },
{ id: 2, component: <Comp2/>, isVisible: true,
info: { id: 6, component: <div>info2</div>, isVisibleInfo: false } },
{ id: 3, component: <Comp3/>, isVisible: true,
info: { id: 7, component: <div>info3</div>, isVisibleInfo: false } },
{ id: 4, component: <Comp4/>, isVisible: true,
info: { id: 8, component: <div>info4</div>, isVisibleInfo: false } }
];
const Test = () => {
const [items, setItems] = useState(array);
const handleClick = (number) => {
const triggeredItems = items.map((item) => {
if (item.id !== number) {
item.isVisible = !item.isVisible;
}
item.info.isVisibleInfo =! item.info.isVisibleInfo
return item;
});
setItems(triggeredItems);
};
return (
<div className="mt-1 pt-1 pb-3 px-3">
<div className="row text-center d-flex my-1">
{items.map(({ id, component, isVisible, info }) => (
isVisible ?
<div
key={id}
className="col-lg-3 col-md-6 mb-4 justify-content-center"
onClick={() => handleClick(id)}
hidden={!isVisible}
>
{ component }
{info.isVisibleInfo ?
<div
key={info.id}
className="col-lg-9 col-md-6 mb-4 justify-content-center"
>
{ info.component }
</div>
: null}
</div>
: null
))}
</div>
</div>
);
};
function App(){
return (
<div>
<Test />
</div>
);
};
// Render
ReactDOM.render(
<App />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
Updating a 3 levels nested array mongoose
Having nested arrays is a bad idea. I would recommend you try a more flat structure to make queries faster and simpler. having said that you can update transactions through:
Data.findOneAndUpdate({
UserId, "60cbbb23d5741b51f8fefc2b"
}, {
$set: {
"peeps.$.arraNames.$[j].Name": "Jess"
}
}, {
arrayFilters: [{
"j._id": {
$eq: "60cbc2d1cf7b1c3250e08dc2"
}
}]
})
Search filter nested array getting modified original array after Object.Assign
your problem is in this lines:
filterTreeRange.treeRanges = filterTreeRange.treeRanges.filter(...);
and
filTreeRange.treeregistered = filTreeRange.treeregistered.filter(...);
you are mutating the treeRanges
and treeregistered
properties instead of returning a modified copy. do an Object.assign to override those properties while keeping the other ones intact instead.
notice that Object.assign
only does a shallow copy, so you ended up modifying the original objects.
here's a fully working demo:
const data = [{
tree: "17200",
treeRanges: [
{
id: 134055,
strttreeNum: "5308550000000000000",
endngtreeNum: "5308559999999999999",
treeregistered: [
{
id: 9,
branch: "12345678989895559"
},
{
id: 10,
branch: "78912349494945449"
}
]
},
{
id: "23175",
strttreeNum: "1234309999999999999",
endngtreeNum: "3466309999999999999",
treeregistered: [
{
id: 14,
branch: "5500001231234234"
},
{
id: 15,
branch: "5598761234444234"
}
]
}
]
}];
const treeRegisteredIncludes = searchTerm => treereg => treereg.branch.includes(searchTerm)
const treeRangesIncludes = searchTerm => treeinRange =>
treeinRange.strttreeNum.includes(searchTerm) ||
treeinRange.endngtreeNum.includes(searchTerm) ||
treeinRange.treeregistered.some(treeRegisteredIncludes(searchTerm))
const itemIncludes = searchTerm => item =>
item.tree.includes(searchTerm) ||
item.treeRanges.some(treeRangesIncludes)
const filterByTerm = (treeRange, searchTerm) => !searchTerm ? treeRange :
treeRange.filter(itemIncludes(searchTerm))
.map(filterTreeRange =>
Object.assign({}, filterTreeRange, {
treeRanges: filterTreeRange.treeRanges
.filter(treeRangesIncludes(searchTerm))
.map(filTreeRange =>
Object.assign({}, filTreeRange, {
treeregistered: filTreeRange.treeregistered.filter(treeRegisteredIncludes(searchTerm))
})
)
})
);
console.log({
filteredBySearchTerm: filterByTerm(data, "444"),
original: data
});
Remove multiple elements from nested arrays
You could take a Set
and filter the values with a lookup and adding the value, if not seen.
const
values = new Set,
data = [['one', 'third'], ['one', 'second', 'fourth'], ['one', 'third']],
result = data.map(a => a.filter(v => !values.has(v) && values.add(v)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Find the biggest number in multidimensional nested arrays in php
Consider the follow idea: if element is array them call the function recursively.
This way you can solve this for any depth of nested arrays.
Pesado code:
function maxInMultiDim($array) {
$max = 0; //assume all num are positive else assign MIN_INT
foreach($array as $elem) {
$temp = $elem;
if (is_array($elem))
$elem = maxInMultiDim($elem);
$max = ($max < $elem ) ? $elem : $max;
}
return $max;
}
Sorry for any syntax mistake...
Related Topics
Laravel Multiple Pagination in One Page
PHP Hierarchical Array - Parents and Childs
Add Columns to Admin Orders List in Woocommerce
PHP Case-Insensitive In_Array Function
Array and String Offset Access Syntax with Curly Braces Is Deprecated
How to Deep Copy a Datetime Object
How Get Value for Unchecked Checkbox in Checkbox Elements When Form Posted
Using Array_Search for Multi Dimensional Array
How to Split a Long String Without Breaking Words
Convert Flat Array to the Multi-Dimensional
The Advantage/Disadvantage Between Global Variables and Function Parameters in PHP
How to Separate Date and Time from Datetime in MySQL
Laravel 5.2 - Use a String as a Custom Primary Key for Eloquent Table Becomes 0