How could I merge duplicate elements from object arrays? [duplicate] - javascript

I have this array of objects, that I need to modify to make it easier the rendering.
const items = [
{
tab: 'Results',
section: '2017',
title: 'Full year Results',
description: 'Something here',
},
{
tab: 'Results',
section: '2017',
title: 'Half year Results',
description: 'Something here',
},
{
tab: 'Reports',
section: 'Marketing',
title: 'First Report',
description: 'Something here',
},
...
];
and I'm trying to modify it, grouping them by specific keys. The idea is to have this output. As you can see the names of the keys could be different than the actual names in the items. I think that makes a bit different from previous posts.
const output = [
{
tab: 'Results',
sections: [
{
section: '2017',
items: [ { 'item that belongs here' }, { ... } ],
},
},
{
tab: 'Reports',
sections: [
{
section: 'Marketing',
items: [ { ... }, { ... } ],
},
},
...
]
I tried using lodash.groupby, but it doesn't do exactly what i'm looking for.
Any idea about how to approach it?
Many thanks!!

This can be done with a clever combinartion of _.map and _.groupBy.
const items = [
{
tab: 'Results',
section: '2017',
title: 'Full year Results',
description: 'Something here',
},
{
tab: 'Results',
section: '2017',
title: 'Half year Results',
description: 'Something here',
},
{
tab: 'Reports',
section: 'Marketing',
title: 'First Report',
description: 'Something here',
}
];
function groupAndMap(items, itemKey, childKey, predic){
return _.map(_.groupBy(items,itemKey), (obj,key) => ({
[itemKey]: key,
[childKey]: (predic && predic(obj)) || obj
}));
}
var result = groupAndMap(items,"tab","sections",
arr => groupAndMap(arr,"section", "items"));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

You could use an object without additional libraries.
The object contains a property _ which keeps the nested arrays of the given nested group.
var items = [{ tab: 'Results', section: '2017', title: 'Full year Results', description: 'Something here' }, { tab: 'Results', section: '2017', title: 'Half year Results', description: 'Something here' }, { tab: 'Reports', section: 'Marketing', title: 'First Report', description: 'Something here' }],
keys = { tab: 'sections', section: 'items' }, // or more if required
result = [],
temp = { _: result };
items.forEach(function (object) {
Object.keys(keys).reduce(function (level, key) {
if (!level[object[key]]) {
level[object[key]] = { _: [] };
level._.push({ [key]: object[key], [keys[key]]: level[object[key]]._ });
}
return level[object[key]];
}, temp)._.push({ title: object.title, description: object.description });
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

Loop through array of objects, if value exists, return another value

With the information below I am trying loop through cards, if there is a nested object of helper, return that objects title. But am either receiving undefined or errors. I was thinking maybe reduce would be viable here?
Sample Array:
cards: [
0: {
title: 'Something',
logo: 'logo link here',
},
1: {
title: 'Something 2',
logo: 'logo link here',
helper: {
text: 'helper text',
},
},
2: {
title: 'Something 3',
logo: 'logo link here',
},
]
code:
cards.filter((item) => {
if (item.helper) setHelperActive({...helperActive, item.title: true})
})
let cards = [
{
title: 'Something',
logo: 'logo link here',
},
{
title: 'Something else',
logo: 'logo link here',
helper: {
text: 'helper text',
},
},
{
title: 'Something',
logo: 'logo link here',
},
{
title: 'Lorem Epsum',
logo: 'logo link here',
helper: {
text: 'helper text',
},
}
]
let filtered = []
for(let i = 0; i < cards.length; i++) {
if(cards[i].helper) {
filtered.push(cards[i].title)
}
}
console.log(filtered);
Using .filter() and checking if the object has a prop named helper. In case of multiple objects matching the criteria, their title's will be joined as a comma-separated string.
Snippet
let cards = [
{
title: 'Something',
logo: 'logo link here',
},
{
title: 'Something 2',
logo: 'logo link here',
helper: {
text: 'helper text',
},
},
{
title: 'Something',
logo: 'logo link here',
},
{
title: 'Something 4',
logo: 'logo link here',
helper: {
text: 'helper text',
},
},
]
// to list titles from all matching objects as a comma-separated string
console.log(cards.filter(ob => 'helper' in ob).map(({ title }) => title).join());
// suppose only the first matched object's title is required
console.log(cards.find(ob => 'helper' in ob)?.title ?? 'no match found');
the solution is to use map not filter should be like this:
var titles = cards.map(card=>{ return card.title })

Easy way to check to see if value exists in a object array?

How to check a value that exists in a nested object?
Lets say I have a data like this:
const data = [
{
title: 'New Posts',
data: [
{
username: 'firstnamefromnewpost',
content: 'this is some content that will go on forever and ever',
},
{
username: 'name',
content:
'lost content goals lets',
},
{
username: 'another name',
content:
'lost content goals lets start with some',
},
],
},
{
title: 'Different Posts',
data: [
{
username: 'usernametag',
content: 'this is some content that will go on forever and ever',
},
{
username: 'name',
content:
'lost content goals lets start',
},
],
},
];
I want to be able to find if firstnamefromnewpost exists within this array. Is there an easy way to do so?
Easy way?
Probably you can use includes() on the stringified array:
const data = [
{
title: 'New Posts',
data: [
{
username: 'firstnamefromnewpost',
content: 'this is some content that will go on forever and ever',
},
{
username: 'name',
content:
'lost content goals lets',
},
{
username: 'another name',
content:
'lost content goals lets start with some',
},
],
},
{
title: 'Different Posts',
data: [
{
username: 'usernametag',
content: 'this is some content that will go on forever and ever',
},
{
username: 'name',
content:
'lost content goals lets start',
},
],
},
];
var isExists = JSON.stringify(data).includes('firstnamefromnewpost');
console.log(isExists);
OR: If you want check the username property in the nested data array:
const data = [
{
title: 'New Posts',
data: [
{
username: 'firstnamefromnewpost',
content: 'this is some content that will go on forever and ever',
},
{
username: 'name',
content:
'lost content goals lets',
},
{
username: 'another name',
content:
'lost content goals lets start with some',
},
],
},
{
title: 'Different Posts',
data: [
{
username: 'usernametag',
content: 'this is some content that will go on forever and ever',
},
{
username: 'name',
content:
'lost content goals lets start',
},
],
},
];
function isExists(data, userName){
for(const i of data){
if(i.data.map(n => n.username).includes(userName)) return true
}
return false;
}
console.log(isExists(data, 'firstnamefromnewpost'));

Unable to create Intent properly in dialogflow using v2 api

I am trying to create intent by using example given in this dialogflow-nodejs-client-v2
, But problem is that it creates Intent with phrases. But it does not create action and responses . I have even tried it using exact code given in example here as below
createIntents('myprojectid')
function createIntents(projectId) {
const dialogflow = require('dialogflow');
const contextsClient = new dialogflow.ContextsClient();
const intentsClient = new dialogflow.IntentsClient();
const agentPath = intentsClient.projectAgentPath(projectId);
const pizzaOutputContexts = [
{
name: contextsClient.contextPath(
projectId,
'' / sessionId */,
'pizza_order'
),
lifespanCount: 5,
},
];
const pizzaResult = {
action: 'pizza',
parameters: [
{
displayName: 'size',
value: '$size',
entityTypeDisplayName: '#SiZe',
mandatory: true,
prompts: [
'What size pizza would you like to order?',
'Would you like a large, medium, or small pizza?',
],
},
{
displayName: 'topping',
value: '$topping',
entityTypeDisplayName: '#Topping',
mandatory: true,
prompts: ['What toppings would you like?'],
isList: true,
},
{
displayName: 'address',
value: '$address',
// The API provides a built-in entity type #sys.address for addresses.
entityTypeDisplayName: '#sys.location',
mandatory: true,
prompts: ['What is the delivery address?'],
},
],
messages: [
{
platform: 'PLATFORM_UNSPECIFIED',
text: {
text: [
'No problem. Getting a $size pizza with $topping and delivering ' +
'to $address.',
]
}
},
{
text: {
text: [
'Reply "check" to place your order. Reply "cancel" to cancel ' +
'your order. You can change your delivery address as well.',
]
}
}
],
outputContexts: pizzaOutputContexts,
};
const pizzaPhrases = [
{type: 'EXAMPLE', parts: [{text: 'Order pizza'}]},
{type: 'EXAMPLE', parts: [{text: 'Pizza'}]},
{
type: 'EXAMPLE',
parts: [
{text: 'Get me a '},
{text: 'large', entityType: '#SiZe', alias: 'size'},
{text: ' '},
{text: 'mushrooms', entityType: '#Topping', alias: 'topping'},
{text: ' for '},
{
text: '1 1st st, New York, NY',
entityType: '#sys.location',
alias: 'address',
},
],
},
{
type: 'EXAMPLE',
parts: [
{text: "I'd like to order a "},
{text: 'large', entityType: '#SiZe', alias: 'size'},
{text: ' pizza with '},
{text: 'mushrooms', entityType: '#Topping', alias: 'topping'},
],
},
{
type: 'TEMPLATE',
parts: [{text: "I'd like a #SiZe:size pizza"}],
},
];
const pizzaIntent = {
displayName: 'Pizza',
events: ['order_pizza'],
// Webhook is disabled because we are not ready to call the webhook yet.
webhookState: 'WEBHOOK_STATE_DISABLED',
trainingPhrases: pizzaPhrases,
mlEnabled: true,
priority: 500000,
result: pizzaResult,
};
const pizzaRequest = {
parent: agentPath,
intent: pizzaIntent,
};
intentsClient
.createIntent(pizzaRequest)
.then(responses => {
console.log('Created Pizza intent:');
// logIntent(responses[0]);
})
.catch(err => {
console.error('ERROR:', err);
});
}
above code creates intent but it does not set action name and responses
As i said before it is exactly same code which is given in dialogflow-nodejs-client-v2. SO is it a bug or i am doing something wrong please help

How to remove treeview child node using jquery

I have a treeview like below, i need to remove one child from the list based on the user. Can any one tell me how to remove the child from the treeview.
var treedata = [
{
label: 'Floor', type: 'Country',
children: [
{
label: 'Bangalore', type: 'Location',
children: [{ label: 'Technopolis', type: 'facility', id: 1 }, { label: 'Ecity Tower-2', type: 'facility', id: 2 }, { label: 'Bagmane', type: 'facility', id: 3 }, { label: 'Cyber Park', type: 'facility', id: 4 }]
},
{
label: 'Hyderabad', type: 'Location',
children: [{ label: 'Hitech City ', type: 'facility', id: 5 }, { label: 'Cyber City', type: 'facility', id: 6 }]
},
{
label: 'Chennai', type: 'Location',
children: [{ label: 'XXX', type: 'facility', id: 7 }]
},
{
label: 'Mumbai', type: 'facility', id: 8
}
]
},
{
label: 'Role Administration', type: 'Role',
children: [{ label: 'Assign Role', type: 'Role', id: 1 }]
},
{
label: 'Hoteling Admin', type: 'Hoteling',
children: [{ label: 'Hoteling', type: 'Hoteling', id: 1 }]
}
];
The above is my jquery tree data. I want to remove the role administration if the user is a normal user by checking the user role.
Anyone help me how to do using jquery.
Thanks
You can use $.grep() to filter the array to a new array based on whatever conditions you want.
var userRole='normal';
if( userRole === 'normal'){
treeview = $.grep(treeview, function(item){
return item.label != 'Role Administration';
});
}
grep() API docs

List Component: How to detect which item was selected?

I can access a list (as a container of items) in a controller but I do not know how to access list items properties.
How to create the correct ComponentQuery rule? I tried 'list > item' but it does not work.
Each item has it's title but I get 'undefined' as output in selectSection.
Ext.define( 'UGP.controller.BeginList',
{
extend: 'Ext.app.Controller',
config:
{
views: [ 'BeginList' ],
control:
{
'list':
{
select: 'selectSection'
}
}
},
selectSection: function()
{
Ext.Msg.alert( 'title=' + this.title );
}
}
);
The BeginList.js with the list component:
Ext.define( 'UGP.view.BeginList',
{
extend: 'Ext.List',
config:
{
fullscreen: true,
itemTpl: '{title}',
data:
[
{ title: 'Chapter 1', id: 0, action: "selectSection" },
{ title: 'Chapter 2', id: 1, action: "selectSection" },
{ title: 'Chapter 3', id: 2, action: "selectSection" },
{ title: 'Chapter 4', id: 3, action: "selectSection" }
]
}
}
);
You can see in the select event documentation that it passes arguments. So you can change the signature of your selectSection function to this :
selectSection: function (list, record) {
Ext.Msg.alert( 'title=' + record.get( 'title' ) );
}
You can also take a look at the itemTap event which usually the one used to detect tap events on a list item.
Hope this helps

Categories

Resources