简体   繁体   中英

Getting array names from multidimensional array

I have a multidimensional array in javascript. I need to loop over the array and everytime the index of the array is equal to an array I have to make a new dropdown menu. To do this I need to get the name of the nested arrays and set it as the name of the dropdown menu.

All the elements in the array represent categories and subcategories. I tried getting for example the name of the array engine, but the only thing I am able to get is the content of the array.

var categories = [engine=[1,2,3, piston=[4,5,6]], tire=[7,8,9]];

What I want to know is if this is even the right way to do it, because I dont think so and I can't seem to find another way of doing it.

Iterating over an object is possible in ES2017 in a much better way than before. Assuming you have a valid object of shape, you could do:

 const tabs = {
    engine: [],
    piston: [],
    tire: []
 };

 Object.entries(tabs) // returns an array of [key, value], here [tab1, []] etc...
    .forEach(([tabname, valueArray]) => {
        // do stuff with it
    });

Of course because order is most likely important you could add an order key for each tab, resulting in a shape like:

 const tabs = {
    engine: { order: 0, indexes: [] },
 };
 // then yo sort before iterating on it.
 Object.entries(tabs).sort(customSortFunction).forEach();

Technically what you posted is a valid array, except that while being created it assigns values to 4 variables all at the same scope level: categories , engine , piston and tire , which could be unintentional.
Expand the collapsed snippet to see a demo of this .

 var categories = [engine=[1,2,3, piston=[4,5,6]], tire=[7,8,9]]; console.log("categories:"); console.log(categories); console.log("engine:"); console.log(engine); console.log("piston:"); console.log(piston); console.log("tire:"); console.log(tire); 


You probably want to use nested object syntax using {} -braces and the : character:

 var categories = [{ engine: [1, 2, 3, { piston: [4, 5, 6] }] }, { tire: [7, 8, 9] }]; console.log("categories:"); console.log(categories); 

You'll need to define that array as an object instead. You can nest objects inside objects as long as it's a property value.

Then you can loop over the object by using Object.values(object)

Eg

 let categories = { engine: [1,2,3, {piston: [4,5,6]}], tire: [7,8,9] }; let values = Object.values(categories); for (let i = 0; i < values.length; i++) { values[i].map(x => { console.log(typeof x); if (typeof x === "object") { //Get the name of the object console.log("> " + Object.keys(x)[0]); } }); } 

Your structure is a purely nested array. The terms "engine", "piston", "tires" are not part of it but are separate variables that are initialised to that particular sub-array.

Instead, I would suggest this structure, where these terms are stored property values, and the nested arrays are stored under the "children" property. So your example would be encoded like this:

var categories = [{ 
    text: "engine",
    children: [1,2,3, { 
        text: "piston",
        children: [4,5,6]
    }]   
}, {
    text: "tire",
    children: [7,8,9]
}];

Some alternatives have been suggested, but be aware that if you use an object like this:

var categories = { 
    engine: [1,2,3, { 
        piston: [4,5,6]
    }
    tire: [7,8,9]
};

...it is shorter, but in theory objects do not impose an order to the properties, so you don't really specify here that "engine" should be listed before "tire". To specify order you need an array (like in your initial plan).

Here is the suggested code to turn the first structure into an HTML menu, using ul and li DOM elements:

 function menuToElement(menu) { const ul = document.createElement("ul"); for (const item of menu) { const li = document.createElement("li"); if (Object(item) === item) { li.textContent = item.text; li.appendChild(menuToElement(item.children)); } else { li.textContent = item; } ul.appendChild(li); } return ul; } var categories = [{ text: "engine", children: [1,2,3, { text: "piston", children: [4,5,6] }] }, { text: "tire", children: [7,8,9] }]; const ul = menuToElement(categories); document.getElementById("menu").appendChild(ul); 
 <div id="menu"></div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM