How do I put my state objects into a 2d array? - javascript

I would like to load these state objects into a 2d array. I need them in the following fashion:
[
[
"josie",
"ally",
"fred"
],
[
"edward",
"ally",
"fred",
"goolly"
]
]
I need it this way because I need a way to reference the sublist relative to the name of the sublist.
class App extends Component {
state = {
List: [
{
name: "josie",
sub: [
"ally",
"fred"
]
},
{
name: "edward",
sub: [
"ally",
"fred",
"goolly"
]
}
]
}
render() {
return (
<div>
</div>
);
}
}
export default App;
I apologize if this is too basic, but I am really beating my head on this.

One of shortest ES6 versions to implement that will be the following:
state.List.forEach(listItem => finalArr.push([].concat([listItem.name], listItem.sub)));
Here we iterate over List array and push to finalArr a new array, which we generate by merging values of name and sub object properties into one new array. And finally we have an array of arrays (each sub array generated from separate items from state.List). Here is the working example:
const state = {
List: [
{
name: "josie",
sub: [
"ally",
"fred"
]
},
{
name: "edward",
sub: [
"ally",
"fred",
"goolly"
]
}
]
}
const finalArr = [];
state.List.forEach(listItem => finalArr.push([].concat([listItem.name], listItem.sub)));
console.log(finalArr);

Related

find and update property of nested object with lodash

I have been scanning through stackoverflow topics and couldn't find answer to the problem i am having.
What i need to do is to find object inside nested (2 depths) array by some of the values and then update other of its values. I managed to put together the finding and also setting seems to work, the problem is that lodash does return main object and it updates main object, not the nested one i actually need.
lets take this structure:
var data = [
{
name: 'I',
status: "0",
categories: [
{
name: 'I1',
status: "0",
specifics: [
{
name: "I1a",
status: "0",
}
]
}
]
}
];
i need to find object inside specifics by its name and then update its status.
so lets try simple find first:
var find = _.find(data, { categories: [ { specifics: [ { name: "I1a" } ] } ]});
this is working but it returns the object with name: I so first main one.
so then if i try to update with this:
var set = _.set(_.find(data, { categories: [ { specifics: [ { name: "I1a" } ] } ]}), 'status', "1");
It also does work but it updates status of I instead of what i was looking for which is I1a.
Is there a way to make finding and therefore setting to return / work on actually queried object ?
var data = [
{
name: 'I',
status: "0",
categories: [
{
name: 'I1',
status: "0",
specifics: [
{
name: "I1a",
status: "0",
}
]
}
]
}
];
var find = _.find(data, { categories: [ { specifics: [ { name: "I1a" } ] } ]})
console.log('find', find);
var set = _.set(_.find(data, { categories: [ { specifics: [ { name: "I1a" } ] } ]}), 'status', "1");
console.log('set', set);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

Is there a better way to iterate through an object of unknown depth than using map statements nested to the maximum possible depth?

I have nested employee objects of different, unknown depths. Each object has a children property, which is an array of the employee objects who report to that employee. These child objects have the same attributes as the top level object and may or may not have employee objects in their own children property.
I need to go through each employee object's array of employee objects and add each of those objects to one of two different arrays, depending on whether the object has other employee objects in it's own "children" property. These arrays are also properties of the employee objects. Employees with empty "children" arrays will be added to their parent employee's nonManagersUnder array, while those with objects in their children array will be added to the managersUnder array.
The nested employee objects look like this:
{
id: "n1",
"isActive": true,
age: 38,
name: "Barb Smith",
"phone": "+1 (882) 547-3581",
"hired": "2016-08-08T12:46:19 +07:00",
children: [
{
id: "n10",
"isActive": true,
age: 37,
name: "Elsie MacDonald",
"phone": "+1 (958) 558-2389",
"hired": "2015-08-15T04:44:49 +07:00",
children: [
]
},
{
id: "n11",
"isActive": true,
age: 29,
name: "Peter Chen",
"phone": "+1 (881) 574-3927",
"hired": "2015-02-16T12:11:11 +08:00",
children: [
]
},
{
id: "n12",
"isActive": true,
age: 32,
name: "Ty Wilder",
"phone": "+1 (990) 506-2830",
"hired": "2019-09-17T06:29:16 +07:00",
children: [
]
}
}
This is a very simple example since I didn't want to put something several hundred lines long in my post, but the structure is the same. Just imagine that each of the secondary employee objects has its own children.
You'll notice that the nonManagersUnder and managersUnder arrays are not attributes of the employee objects to start with. That is because in my current solution they are dynamically assigned.
Here is that solution:
countManagers = (employee) => {
let midManagers = []
let nonManagers = []
employee.children.map(child =>{
if(child.children.length == 0) {
nonManagers.push(child);
}else {
midManagers.push(child);
child.children.map(grandChild => {
if(grandChild.children.length == 0){
nonManagers.push(grandChild);
}else {
midManagers.push(grandChild);
grandChild.children.map(greatGrand => {
if(greatGrand.children.length == 0){
nonManagers.push(greatGrand)
} else {
midManagers.push(greatGrand);
greatGrand.children.map(grand3 => {
if(grand3.children.length==0){
nonManagers.push(grand3);
} else {
midManagers.push(grand3);
grand3.children.map(grand4 => {
if(grand4.children.length==0){
nonManagers.push(grand4);
} else {
midManagers.push(grand4);
}
})
}
})
}
})
}
})
}
})
console.log(midManagers);
// console.log(nonManagers);
employee.managersUnder = (midManagers);
employee.nonManagersUnder=(nonManagers)
}
As you can see, it is simply nested map operators and some conditionals, nested to the maximum depth an employee object can be nested. This solution does work, but is very ugly and I'm almost certain there is a better way of doing this. A better solution would work for an object of any depth. This only works for objects where the depth is equal to or less than the number of nested map operators.
I wanted to refresh some recursion stuffs and came out with a solution for you query.
const values = [{
id: "n1",
children: [{
id: "n10",
children: [{
id: "n100",
children: []
}, ]
},
{
id: "n11",
children: []
},
{
id: "n12",
children: []
}
]
}]
const getAllManagers = (employees) => {
return employees.reduce((acc, emp) => {
return acc.concat(emp.children.length > 0 ? [emp, ...getAllManagers(emp.children)] : [])
}, [])
}
const getAllNonManagers = (employees) => {
return employees.reduce((acc, emp) => {
return acc.concat(emp.children.length > 0 ? getAllNonManagers(emp.children) : emp)
}, [])
}
console.log("Managers: ", getAllManagers(values))
console.log("NonManagers:", getAllNonManagers(values))

Using map in a multidimensional array Javascript

I have this set of data that I'm trying to convert to map:
x = [
{
food: 'Steak',
ingredients: [
{
item1: 'pepper',
},
{
item2: "salt",
},
],
},
{
food: 'Veggies'
},
{
food: 'Fruits'
},
];
This is my current map function, question is how do I iterate on the ingredients?:
<div>
{Object.keys(x).map(key => (
<a key={key}>{x[key].food}</a>
))}
</div>
Something like this?
x = [
{
food: 'Steak',
ingredients: [
{
item1: 'pepper',
},
{
item2: "salt",
},
],
},
{
food: 'Veggies'
},
{
food: 'Fruits'
},
];
const list = x.map(item =>
({[item.food]: item.ingredients ?
item.ingredients.flatMap(i =>
Object.keys(i).map(k =>
i[k])).join(','): 'no ingredients'}))
console.log(list)
Output:
[
{
"Steak": "pepper,salt"
},
{
"Veggies": "no ingredients"
},
{
"Fruits": "no ingredients"
}
]
A better format for the data:
x = [
{
food: 'Steak',
ingredients: [
"pepper", "salt",
],
},
{
food: 'Veggies'
},
{
food: 'Fruits'
},
];
Naming things is 80% of programming. The other 20% is choosing the right font for your IDE.
If you have an array of objects and the key of object holds no semantic meaning, and there is one key in each object, that's a sign that it should be an array.
You could go one step further:
const ingredients = {
Steak: ["pepper", "salt"],
Veggies: []
Fruits: []
};
The name of the data structure makes sense. It is an "ingredients by food" object.
Where you went off is starting with x as the name of the object. x is an unknown. Start by describing everything clearly, and use JetBrains Mono.
If you want to easily iterate over the object using map (like to render a table in React), then you could do:
const ingredients = [
{Steak: ["pepper", "salt"]},
{Veggies: []},
{Fruits: []}
];
or:
const recipes = [
{food: Steak, ingredients: ["pepper", "salt"]},
{food: Veggies, ingredients: []},
{food: Fruits, ingredients: []}
];
(which is close to the reduction I did to your original data)
That one should be called recipes, which I discovered when I wrote this next function and the names didn't make sense if the object were named ingredients.
recipes.forEach(recipe => {
console.log(`HTML Title: %{recipe.food})
console.log(`HTML Subtitle: Ingredients`)
recipe.ingredients.forEach(ingredient =>
console.log(`* ${ingredient}`)
)
})
See, the names in the data structure make sense, and so do the functions to work with it. And the data structure itself is small and comprehensible. Structure is also data.
JetBrains Mono.
You can store all ingredientItem in one array and then apply Map on that array:
let ingredientItem = [];
x.forEach((item) => {
if (item.ingredients) {
item.ingredients.forEach((ingredient) => {
for (name in ingredient) {
ingredientItem.push(ingredient[name])
}
})
}
})
ingredientItem.map((item) => {
})

Divide a Javascript Array and subarrays In 2 arrays

I have this array:
var myArray = [
{ familyName: 'one', subfamilies:
[ { subfamilyName: 'subOne', subItems:
[ { name: 'subOne', code: '1' },
{ name: 'subTwo', code: '2' }
] }
]
},
{ familyName: 'two', subfamilies:
[ { subfamilyName: 'subTwo', subItems:
[ { name: 'subOne', code: '1' },
{ name: 'subTwo', code: '2' },
{ name: 'subTwo', code: '3' }
] }
]
}
]
I need to divide that array in two diferent arrays with the same length if possible (my real array is so much longer), but I am having some problems getting it done. I create 2 blank array and, with for sentence read all the items. First I push the subItems in one blank array, but cannot get the way to create a new subFamily in a blank array variable and then push the sutItems array.
How can be this done?
Thanks a lot in advance.
var myOtherArray = myArray.splice(myArray.length / 2 | 0);

Iterating a javascript collection and adding a sort order

I have a tree in javascript which has multiple root elements and nested children.
Here's the object:
[{
_id: '546d30905d7edd1d5169181d',
name: 'first'
children: []
}, {
_id: '546d30905d7edd1d2169181d',
name: 'second'
children: []
}, {
_id: '446d30905d7edd1d5169181d',
name: 'third',
children: [{
_id: '446d30905d7e2d1d5169181d',
name: '3child',
children: []
}, {
_id: '446d30915d7e2d1d5169181d',
name: '3child2',
children: [{
_id: '546d30905d7edd1d2569181d',
name: 'second2',
children: []
}]
}]
}, {
_id: '546d30995d7edd1d5169181d',
name: 'fourth',
children: []
}]
This is a truncated document that's being stored in MongoDB using materialized path. The issue is that I need to add a 'sorting' ability, so nodes in the same root can be sorted.
I want to iterate this tree and apply a sort_value such as node['sort_value'] = 0, etc.
Each level will have it's own sort order, starting at 0.
I can simply iterate the tree recursively:
function iterate(items) {
_.each(items, function(page, key) {
if (items.children.length > 0) {
iterate(items.children);
}
});
}
However, I can't figure out how to keep track of the sort orders and also update the object's to include the sort_value field.
Any help would be greatly appreciated! Thank you
I did it so that I used array key for sorting and "synchronized" it with object property (because I needed it saved to DB and restored after) and it works as a charm :)
So something like this, pseudo:
var unsorted = [
0:{"sort_key": "0", "data":"dataaa 0"},
1:{"sort_key": "1", "data":"dataaa 1"},
...
n:{"sort_key": "n", "data":"dataaa n"}
];
function_sort(unsorted){
...
return sorted = [
0:{"sort_key": "n", "data":"dataaa y"},
1:{"sort_key": "44", "data":"dataaa x"},
...
n:{"sort_key": "0", "data":"dataaa z"}
];
}
save = function_save(sorted){
...update sort_key as array key...
return for_saving;
}

Categories