Destructuring first object of array in JavaScript [duplicate] - javascript

This question already has an answer here:
To access property of object nested in array using destructuring
(1 answer)
Closed 12 months ago.
Let's say we have the object below:
const page = {
name: 'Page 1',
page_category: [
{
postId: 1,
catId: 1,
category: {
id: 1,
name: 'category 1'
}
},
{
postId: 3,
catId: 2,
category: {
id: 2,
name: 'category 2'
}
},
]
}
To get the first object in the page_category array, in a destructuring manner, We would do this:
const { page_category: [first] } = page
But what would it be if we wanted to get the first object's category field?

You can destructure the object within the array destructuring:
const { page_category: [{category}] } = page;
const page = {
name: 'Page 1',
page_category: [{
postId: 1,
catId: 1,
category: {
id: 1,
name: 'category 1'
}
},
{
postId: 3,
catId: 2,
category: {
id: 2,
name: 'category 2'
}
},
]
};
const { page_category: [{category}] } = page;
console.log(category);
The destructuring assignment syntax is analogous to the syntax of creating the object literal, the below formatting shows how they have the same shape. You can use this idea to assist with your destructuring patterns:
const {
page_category: [
{
category
}
]
} = page;

To destructure the first object's category field.
const {page_category: [ {category} ]} = page;
console.log("category ==>", category);
This way you will find the first category object.

Related

Group array of objects by multiple nested values

I have an array of objects which presents tasks. These tasks are categorized (primary / secondary category).
let tasks = [
{
id: 1,
name: 'Cleanup desk',
primary_category: {
id: 1,
name: 'Indoor'
},
secondary_category: {
id: 2,
name: 'Surfaces'
}
},
{
id: 2,
name: 'Cleanup office floors',
primary_category: {
id: 1,
name: 'Indoor'
},
secondary_category: {
id: 3,
name: 'Ground'
}
},
{
id: 3,
name: 'Water plants',
primary_category: {
id: 2,
name: 'Outdoor'
},
secondary_category: {
id: 3,
name: 'Irrigation'
}
}
];
I now try to create a categories accordion in my frontend and therefore need to group my array differently. The structure should look like:
1) primary category
> secondary category
> tasks
> secondary category
> tasks
2) primary category
> secondary category
> tasks
Therefore I'm trying to achieve a structure similar to this:
let tasks_categorized = [
{
id: 1,
name: 'Indoor',
secondary_categories: [
{
id: 2,
name: 'Surfaces',
tasks: [
{
id: 1,
name: 'Cleanup desk'
}
]
},
{
id: 3,
name: 'Ground',
tasks: [
{
id: 2,
name: 'Cleanup office floors'
}
]
}
]
},
{
id: 2,
name: 'Outdoor',
secondary_categories: [
{
id: 3,
name: 'Irrigation',
tasks: [
{
id: 3,
name: 'Water plants'
}
]
}
]
}
];
I tried using groupBy by lodash but this does not allow grouping by multiple nested key-value pairs. Does anybody know an approach to solve this?
Thank you in advance!
The following provided approach is going to achieve the expected result within a single reduce cycle without any further nested loops.
It does so by implementing a reducer function which creates and/or aggregates at time a prioritized category task while iterating another task array. But most importantly it keeps track of a task item's related primary and secondary categories via a Map based lookup. This lookup reference together with a result array are properties of this function's return value which has to be partly provided as the reduce method's initial value as follows ... { result: [] }.
function createAndAggregatePrioritizedCategoryTask(
{ lookup = new Map, result }, item
) {
const { primary_category, secondary_category, ...taskRest } = item;
const { id: primaryId, name: primaryName } = primary_category;
const { id: secondaryId, name: secondaryName } = secondary_category;
const primaryKey = [primaryId, primaryName].join('###');
const secondaryKey = [primaryKey, secondaryId, secondaryName].join('###');
let primaryCategory = lookup.get(primaryKey);
if (!primaryCategory) {
// create new primary category item.
primaryCategory = {
id: primaryId,
name: primaryName,
secondary_categories: [],
};
// store newly created primary category reference in `lookup`.
lookup.set(primaryKey, primaryCategory);
// push newly created primary category reference to `result`.
result.push(primaryCategory);
}
let secondaryCategory = lookup.get(secondaryKey);
if (!secondaryCategory) {
// create new secondary category item.
secondaryCategory = {
id: secondaryId,
name: secondaryName,
tasks: [],
};
// store newly created secondary category reference in `lookup`.
lookup.set(secondaryKey, secondaryCategory);
// push newly created secondary category reference into the
// `secondary_categories` array of its related primary category.
primaryCategory
.secondary_categories
.push(secondaryCategory);
}
// push the currently processed task-item's rest-data as
// item into the related secondary category's `task` array.
secondaryCategory
.tasks
.push(taskRest);
return { lookup, result };
}
let tasks = [{
id: 1,
name: 'Cleanup desk',
primary_category: { id: 1, name: 'Indoor' },
secondary_category: { id: 2, name: 'Surfaces' },
}, {
id: 2,
name: 'Cleanup office floors',
primary_category: { id: 1, name: 'Indoor' },
secondary_category: { id: 3, name: 'Ground' },
}, {
id: 3,
name: 'Water plants',
primary_category: { id: 2, name: 'Outdoor' },
secondary_category: { id: 3, name: 'Irrigation' },
}];
const { result: tasks_categorized } = tasks
.reduce(createAndAggregatePrioritizedCategoryTask, { result: [] });
console.log({ tasks_categorized });
.as-console-wrapper { min-height: 100%!important; top: 0; }
You could take a dynamic approach with an array of arrays with functions and keys for the nested arrays.
const
tasks = [{ id: 1, name: 'Cleanup desk', primary_category: { id: 1, name: 'Indoor' }, secondary_category: { id: 2, name: 'Surfaces' } }, { id: 2, name: 'Cleanup office floors', primary_category: { id: 1, name: 'Indoor' }, secondary_category: { id: 3, name: 'Ground' } }, { id: 3, name: 'Water plants', primary_category: { id: 2, name: 'Outdoor' }, secondary_category: { id: 3, name: 'Irrigation' } }],
groups = [
[o => o, 'primary category'],
[o => o.primary_category, 'secondary category'],
[o => o.secondary_category, 'tasks']
],
result = tasks.reduce((r, o) => {
groups.reduce((parent, [fn, children]) => {
const { id, name } = fn(o);
let item = (parent[children] ??= []).find(q => q.id === id)
if (!item) parent[children].push(item = { id, name });
return item;
}, r);
return r;
}, {})[groups[0][1]];
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Compare Javascript Object field with another Object field [duplicate]

This question already has answers here:
Merge two array of objects based on a key
(23 answers)
Closed last year.
I have two Objects one of them has the Store Name and the other object has the Price for an item along with the Store ID on both objects. Such as;
obj1 = [
{id: 1,name: "Store1"},
{id: 2,name: "Store2"},
{id: 3,name: "Store3"}
];
obj2= [
{ id: 1, price: 100 },
{ id: 2, price: 200 },
{ id: 3, price: 300 }
];
What I want to achieve is that compare obj1 id with obj2 id if they are the same get the price and the store name from the same id. What is the best way to achieve this? I have been trying to use Array.map or filter but can't really make it work. Thank you!
You can use map & find
const obj1 = [{
id: 1,
name: "Store1"
},
{
id: 2,
name: "Store2"
},
{
id: 3,
name: "Store3"
},
{
id: 4,
name: "Store3"
}
];
const obj2 = [{
id: 1,
price: 100
},
{
id: 2,
price: 200
},
{
id: 3,
price: 300
}
];
const newData = obj1.map((item, index) => {
return {
...item,
// if the item exist in obj2 then get the price else assign empty string
price: obj2.find(elem => elem.id === item.id) ? .price || ''
}
});
console.log(newData)

Find Duplicate Object in List and Add Parameters

I am trying to find duplicate objects in a list of objects and add new parameters to the duplicate one.
Below snipped code is what I implemented so far. The problem is that it adds desired parameters to every object in the list.
const list = [{
id: 1,
name: 'test1'
},
{
id: 2,
name: 'test2'
},
{
id: 3,
name: 'test3'
},
{
id: 2,
name: 'test2'
}
];
const newList = list.reduce(
(unique, item) => (unique.includes(item) ? unique : [...unique, {
...item,
duplicated: true,
name: `${item.name}_${item.id}`
}]), []
);
console.log(newList);
Since there are two duplicate objects by id, the duplicated one should have duplicated and new name parameters. What part is wrong in my implementation?
By using findIndex method:
const list = [{
id: 1,
name: 'test1'
},
{
id: 2,
name: 'test2'
},
{
id: 3,
name: 'test3'
},
{
id: 2,
name: 'test2'
}
];
const newList = list.reduce(
(unique, item) => (unique.findIndex(x => x.id === item.id) > -1 ? [...unique, {
...item,
duplicated: true,
name: `${item.name}_${item.id}`
}] : [...unique, item]), []);
console.log(newList);
It can be written simply:
const
list = [
{ id: 1, name: 'test1' },
{ id: 2, name: 'test2' },
{ id: 3, name: 'test3' },
{ id: 2, name: 'test2' }
],
uniqueList = list.reduce((arr, { id, name }) =>
arr.concat({
id,
name,
...arr.some(item => id === item.id) && { duplicate: true, name: `${name}_${id}` }
}), []);
console.log(uniqueList);
The problem was that when you called includes you were actually looking for an object whose pointer exists in the array.
In order to find an object which has property are the same as a requested property, you have no choice but to use functions such as some or every that is different from includes - you can send them a callback and not just an object.

Remove attribute from JSON objects in a array [duplicate]

This question already has answers here:
How do I remove a property from a JavaScript object?
(37 answers)
Loop through an array in JavaScript
(46 answers)
Closed 4 years ago.
I have an array of json objects.
var user =[ { id: 1, name: 'linto', img: 'car' },
{ id: 2, name: 'shinto', img: 'ball' },
{ id: 3, name: 'hany', img: 'kite' } ]
From this is want to remove attribute img from all the elements of the array, so the output looks like this.
var user =[ { id: 1, name: 'linto' },
{ id: 2, name: 'shinto' },
{ id: 3, name: 'hany' } ]
Is there a way to do this in java script.
You can use .map() with Object Destructuring:
let data =[
{ id: 1, name: 'linto', img: 'car' },
{ id: 2, name: 'shinto', img: 'ball' },
{ id: 3, name: 'hany', img: 'kite' }
];
let result = data.map(({img, ...rest}) => rest);
console.log(result);
Array.prototype.map()
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
You can use map() in the following way:
var user =[ { id: 1, name: 'linto', img: 'car' },
{ id: 2, name: 'shinto', img: 'ball' },
{ id: 3, name: 'hany', img: 'kite' } ]
user = user.map(u => ({id: u.id, name: u.name}));
console.log(user);

ES6 map an array of objects, to return an array of objects with new keys [duplicate]

This question already has answers here:
ECMAScript 6 arrow function that returns an object
(6 answers)
Closed 6 years ago.
I have an array of objects:
[
{
id: 1,
name: 'bill'
},
{
id: 2,
name: 'ted'
}
]
Looking for a simple one-liner to return:
[
{
value: 1,
text: 'bill'
},
{
value: 2,
text: 'ted'
}
]
So I can easily pump them into a react dropdown with the proper keys.
I feel like this simple solution should work, but I'm getting invalid syntax errors:
this.props.people.map(person => { value: person.id, text: person.name })
You just need to wrap object in ()
var arr = [{
id: 1,
name: 'bill'
}, {
id: 2,
name: 'ted'
}]
var result = arr.map(person => ({ value: person.id, text: person.name }));
console.log(result)

Categories

Resources