Create an array based on two arrays - javascript

I have two arrays details and options that coming from different sources (web api requests)
details: [
{ id: 'groups', option: true },
{ id: 'category', option: false }
]
options: {
groups: [
{ id: 'g1' },
{ id: 'g2' }
],
category: [
{ id: 'c1' },
{ id: 'c2' }
],
other: [
{ id: 'o1' },
{ id: 'o2' }
],
}
I want to combine these tow arrays like
combined: [
groups:
{
options:[
{ id: 'g1' },
{ id: 'g2' }
],
details: { option: true}
},
category:
{
options: [
{ id: 'c1' },
{ id: 'c2' }
],
details: { option: false}
},
]
Basically if any id from details is matching to options property it should go in to new array under the same property name and all details except id goes to related details property.
What is the best way of doing that? Is lodash can handle that ?

If you only want the items in both options and details (intersection):
var details = [
{ id: 'groups', option: true },
{ id: 'category', option: false }
]
var options = {
groups: [
{ id: 'g1' },
{ id: 'g2' }
],
category: [
{ id: 'c1' },
{ id: 'c2' }
],
other: [
{ id: 'o1' },
{ id: 'o2' }
]
}
var combined = {};
details.forEach(({id: id, option: option}) => {
if (options[id]) {
combined[id] = combined[id] || {};
combined[id].options = options[id];
combined[id].details = {option: option};
}
})
console.log(JSON.stringify(combined, null, "\t"))
/*
{
"groups": {
"options": [
{
"id": "g1"
},
{
"id": "g2"
}
],
"details": {
"option": true
}
},
"category": {
"options": [
{
"id": "c1"
},
{
"id": "c2"
}
],
"details": {
"option": false
}
}
}
*/
If you want to retain all items from options and details whether or not they match (union):
var details = [
{ id: 'groups', option: true },
{ id: 'category', option: false }
]
var options = {
groups: [
{ id: 'g1' },
{ id: 'g2' }
],
category: [
{ id: 'c1' },
{ id: 'c2' }
],
other: [
{ id: 'o1' },
{ id: 'o2' }
]
}
var combined = {};
Object.keys(options).forEach(id => {
combined[id] = {};
combined[id].options = options[id];
})
details.forEach(({id: id, option: option}) => {
combined[id] = combined[id] || {};
combined[id].details = {option: option};
})
console.log(JSON.stringify(combined, null, "\t"))
/*
{
"groups": {
"options": [
{
"id": "g1"
},
{
"id": "g2"
}
],
"details": {
"option": true
}
},
"category": {
"options": [
{
"id": "c1"
},
{
"id": "c2"
}
],
"details": {
"option": false
}
},
"other": {
"options": [
{
"id": "o1"
},
{
"id": "o2"
}
]
}
}
*/

You need to use [] notation to push details values.
options['groups']['details'] = true
options['groups']['category'] = false

Here's the solution for your problem
var details= [
{ id: 'groups', option: true },
{ id: 'category', option: false }
];
var options= {
groups: [
{ id: 'g1' },
{ id: 'g2' }
],
category: [
{ id: 'c1' },
{ id: 'c2' }
],
other: [
{ id: 'o1' },
{ id: 'o2' }
],
};
var combined = {};
for (var i= 0;i<details.length;i++){
var obj = {}
obj.options=options[details[i].id];
obj.details = {};
obj.details.option=details[i].option;
combined[details[i].id] = obj;
}
console.log(combined)

Related

How to compare two array of objects and return the not matching object?

obj1 is the original object and obj2 is the changed object. I want to get the key , value pair and the type of all the changed object inside obje2 array of objects.
So, I need something like this where if "name" or "id" value is different in obj2 return the object along with the type.
changedObj = [
{
type:"mobile",
name:"Temple Runs",
id:2259
},
{
type:"pc",
name:"Pubgs",
id:222
}
]
obj1 = [
{
type: "mobile",
games: [
{
name: "Temple Run",
id: 2259,
},
{
name: "Subway Surfer",
id: 2271,
},
{
name: "Pubg",
id: 2272,
},
],
},
{
type: "pc",
games: [
{
name: "Pubg",
id: 222,
},
{
name: "Fortnite",
id: 2274,
},
{
name: "Nfs",
id: 2272,
},
],
},
];
obj2 = [
{
type: "mobile",
games: [
{
name: "Temple Runs",
id: 2259,
},
{
name: "Subway Surfer",
id: 2271,
},
{
name: "Pubg",
id: 2272,
},
],
},
{
type: "pc",
games: [
{
name: "Pubgs",
id: 222,
},
{
name: "Fortnite",
id: 2274,
},
{
name: "Nfs",
id: 2272,
},
],
},
];
How to achieve something like this ?
In order to find the difference, you will need to:
Map all of the updated platforms (type and games)
Filter the updated games and locate the original game by ID
Flat-map the games in each platform and include the type
const main = () => {
const delta = diff(changed, data);
console.log(delta);
};
const diff = (updated, original) =>
updated
.map(({ type, games }) => ({
type,
games: games
.filter(({ name, id }) => original
.find(platform => platform.type === type).games
.find(game => game.id === id)?.name !== name)
}))
.flatMap(({ type, games }) =>
games.map(({ name, id }) =>
({ name, id, type })));
const data = [{
type: "mobile",
games: [
{ name: "Temple Run", id: 2259 },
{ name: "Subway Surfer", id: 2271 },
{ name: "Pubg", id: 2272 }
],
}, {
type: "pc",
games: [
{ name: "Pubg", id: 222 },
{ name: "Fortnite", id: 2274 },
{ name: "Nfs", id: 2272 }
]
}];
const changed = [{
type: "mobile",
games: [
{ name: "Temple Runs", id: 2259 },
{ name: "Subway Surfer", id: 2271 },
{ name: "Pubg", id: 2272 }
],
}, {
type: "pc",
games: [
{ name: "Pubgs", id: 222 },
{ name: "Fortnite", id: 2274 },
{ name: "Nfs", id: 2272 }
]
}];
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }

Filter based off of nested object

Trying to figure out the best way to filter the nested object to get every category with an id of '2' or whatever. Want it so it only return those specific nodes.
const data = [
{
node: {
categories: [
{id: 2 }
]
}
},
{
node: {
categories: [
{id: 3}
]
}
},
{
node: {
categories: [
{id: 3}
]
}
},
{
node: {
categories: [
{ id: 5 }
]
}
},
{
node: {
categories: [
{ id: 2 }
]
}
},
]
Tried something like this but doesn't seem to work.
return data.filter(e => {
return e.node.categories.forEach(category => {
category.id == '2';
});
});
If you want to return any node which has a category id of 2, you can filter based on some of the id values being equal to 2:
const data = [
{
node: { categories: [ { id: 2 } ] }
},
{
node: { categories: [ { id: 3 } ] }
},
{
node: { categories: [ { id: 3 } ] }
},
{
node: { categories: [ { id: 5 } ] }
},
{
node: { categories: [ { id: 2 } ] }
},
]
const result = data.filter(e => e.node.categories.some(c => c.id == 2));
console.log(result);
we can use find to search if the category contain specific id or not.
const data = [
{
node: {
categories: [{ id: 2 }],
},
},
{
node: {
categories: [{ id: 3 }],
},
},
{
node: {
categories: [{ id: 3 }],
},
},
{
node: {
categories: [{ id: 5 }],
},
},
{
node: {
categories: [{ id: 2 }],
},
},
];
const result = data.filter(({ node }) => {
return node.categories.find((cat) => cat.id === 2);
});
console.log(result);

How can I iterate over an array?

I have this JSON structure:
const arr = [
{
id: "TaskStatuses",
rows: [
{id: "1", name: "Success"},
{id: "2", name: "Error"},
]
},
{
id: "Objects",
rows: [
{id: "1", name: "Object1"},
{id: "2", name: "Object2"},
]
},
{
id: "Groups",
rows: [
{id: "1", name: "Group1"},
{id: "2", name: "Group2"},
]
},
]
I need to create array with some condition. If my condition correctly I will push elements arr.rows.
Finally i want to get this structure:
[
{
Objects: "Object1",
Groups: "Group1"
},
{
Objects: "Object2",
Groups: "Group2"
}
]
I try to do like this
let sites = []
for (let el in arr) {
if (arr.id == "Objects") {
for (let item of el.rows) {
sites.push({Objects: item.name})
}
}
if (arr.id == "Groups") {
for (let item of el.rows) {
sites.Groups = item.name
}
}
}
You could map the wanted properties in new objects.
const
data = [{ id: "TaskStatuses", rows: [{ id: "1", name: "Success" }, { id: "2", name: "Error" }] }, { id: "Objects", rows: [{ id: "1", name: "Object1" }, { id: "2", name: "Object2" }] }, { id: "Groups", rows: [{ id: "1", name: "Group1" }, { id: "2", name: "Group2" }] }],
ids = ['Objects', 'Groups'],
result = data.reduce((r, { id, rows }) => ids.includes(id)
? rows.map(({ name }, i) => ({ ...r[i], [id]: name }))
: r,
[]
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to insert entries from into a nested JavaScript Object

I'm facing trouble in making a nested insertion of a particular entry into my data structure. The 'positionValue' in the 'data' object below has to be inserted into 'mystructure' based on whether it is Team1 or Team2, and based on the category 'Lombard Loans/Time Deposits/Demand Deposits' and then further based on 'name' of the product (the last nested structure).
The original object:
data: [
{
balanceSheetPositionResults: [
{
positionValue: 12,
balanceSheetPosition: {
name: "asset_bc_lombard_a_onsight",
category: "LOMBARD_LOANS",
type: "ASSET"
},
},
{
positionValue: 58,
balanceSheetPosition: {
name: "liability_bc_timedeposits",
category: "TIME_DEPOSITS",
type: "ASSET"
},
},
{
positionValue: 58,
balanceSheetPosition: {
name: "liability_bc_demanddeposits",
category: "DEMAND_DEPOSITS",
type: "ASSET"
},
},
{
positionValue: 10,
balanceSheetPosition: {
name: "asset_bc_lombard_a_lt1m",
category: "LOMBARD_LOANS",
type: "ASSET"
},
}
],
bank: {
name: "Team1"
},
game: {
name: "TestGame"
},
bsSum: 2,
period: {
index: 1
},
},
{
balanceSheetPositionResults: [
{
positionValue: 12,
balanceSheetPosition: {
name: "asset_bc_lombard_a_onsight",
category: "LOMBARD_LOANS",
type: "ASSET"
},
},
{
positionValue: 58,
balanceSheetPosition: {
name: "liability_bc_timedeposits",
category: "TIME_DEPOSITS",
type: "ASSET"
},
},
{
positionValue: 58,
balanceSheetPosition: {
name: "liability_bc_demanddeposits",
category: "DEMAND_DEPOSITS",
type: "ASSET"
},
},
{
positionValue: 10,
balanceSheetPosition: {
name: "asset_bc_lombard_a_lt1m",
category: "LOMBARD_LOANS",
type: "ASSET"
},
}
],
bank: {
name: "Team2"
},
game: {
name: "TestGame"
},
bsSum: 2,
period: {
index: 1
}
}
]
The structure that I made after some transformation (this is just a snippet):
{ mystructure:
[
{ name: 'Team2',
LOMBARD_LOANS:
[ { name: 'asset_bc_lombard_a_onsight'
},
{ name: 'asset_bc_lombard_a_lt1m'
}
],
DEMAND_DEPOSITS:
[ { name: 'liability_bc_demanddeposits'
}
],
TIME_DEPOSITS:
[ { name: 'liability_bc_timedeposits'
}
]
},
{ name: 'Team1',
LOMBARD_LOANS:
[ { name: 'asset_bc_lombard_a_onsight'
},
{ name: 'asset_bc_lombard_a_lt1m'
}
],
DEMAND_DEPOSITS:
[ { name: 'liability_bc_demanddeposits'
}
],
TIME_DEPOSITS:
[ { name: 'liability_bc_timedeposits'
}
]
}
]
}
The result that would look like:
{ mystructure:
[
{ name: 'Team2',
LOMBARD_LOANS:
[ { name: 'asset_bc_lombard_a_onsight',
positionValue: 12
},
{ name: 'asset_bc_lombard_a_lt1m',
positionValue: 58
}
],
DEMAND_DEPOSITS:
[ { name: 'liability_bc_demanddeposits',
positionValue: 58
}
],
TIME_DEPOSITS:
[ { name: 'liability_bc_timedeposits',
positionValue: 10
}
]
},
{ name: 'Team1',
LOMBARD_LOANS:
[ { name: 'asset_bc_lombard_a_onsight',
positionValue: 12
},
{ name: 'asset_bc_lombard_a_lt1m',
positionValue: 58
}
],
DEMAND_DEPOSITS:
[ { name: 'liability_bc_demanddeposits',
positionValue: 58
}
],
TIME_DEPOSITS:
[ { name: 'liability_bc_timedeposits',
positionValue: 10
}
]
}
]
}
Assuming each bank name comes only once, pass your original array to this transformer :
function transformData(data) {
return data.map(entry => {
const loanType = {};
entry.balanceSheetPositionResults.forEach(balanceEntry => {
const { name, category, type } = balanceEntry.balanceSheetPosition;
if (!(category in loanType)) {
loanType[category] = [];
}
loanType[category].push({
name,
positionValue: balanceEntry.positionValue
});
});
return {
name: entry.bank.name,
...loanType
};
});
}

how to filter nested array like this?

I am having response like below
let m = [
{
name: 'Summary',
subListExpanded: false,
subList: [
]
},
{
name: 'Upload',
subListExpanded: false,
subList: [
]
},
{
name: 'Tasks',
subListExpanded: false,
subList: [
]
},
{
name: 'Dashboard',
subListExpanded: false,
subList: [
]
},
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'user-master',
name: 'User-Master'
},
{
id: 'menu-master',
name: 'Menu-Master'
},
{
id: 'entity-master',
name: 'Entity-Master'
},
{
id: 'vendor-master',
name: 'Vendor-Master'
},
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
If i search m the filter should be like this
[
{
name: 'Summary',
subListExpanded: false,
subList: [
]
},
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'user-master',
name: 'User-Master'
},
{
id: 'menu-master',
name: 'Menu-Master'
},
{
id: 'entity-master',
name: 'Entity-Master'
},
{
id: 'vendor-master',
name: 'Vendor-Master'
},
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
if i search master the filter response should like this?
[
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'user-master',
name: 'User-Master'
},
{
id: 'menu-master',
name: 'Menu-Master'
},
{
id: 'entity-master',
name: 'Entity-Master'
},
{
id: 'vendor-master',
name: 'Vendor-Master'
},
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
if i search xxx-master the filter response should be
[
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
if i search slkvcsmcskc filter response like
[]
my typescript code is not working properly .please help me to fix this>
m.filter(x=> x.name.toLowerCase() === search.toLowerCase() || x.subList.some(x1=> x1.name.toLowerCase()===search.toLowerCase()))
The following code gives the desired output. Note that I added some complexity which may not be needed for your use case. However, the example should work for lists with arbitrary deep nesting (see 'bar' example).
let m = [
{
name: 'Summary',
subListExpanded: false,
subList: [
]
},
{
name: 'Upload',
subListExpanded: false,
subList: [
{
name: 'foo',
subList: [
{
name: 'bar',
}
],
}
]
},
{
name: 'Tasks',
subListExpanded: false,
subList: [
]
},
{
name: 'Dashboard',
subListExpanded: false,
subList: [
]
},
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'user-master',
name: 'User-Master'
},
{
id: 'menu-master',
name: 'Menu-Master'
},
{
id: 'entity-master',
name: 'Entity-Master'
},
{
id: 'vendor-master',
name: 'Vendor-Master'
},
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
function search (input, query) {
const queryReg = new RegExp(query, 'i');
function searchInternal (data) {
let result = [];
data.forEach(item => {
const parentMatch = queryReg.test(item.name);
let subMatch = false;
if (item.subList) {
let subResult = searchInternal(item.subList);
subMatch = subResult.length > 0;
item.subList = subMatch ? subResult : [];
}
// push parent if it matches for itself or a child (list) matches
if (parentMatch || subMatch) result.push(item);
});
return result;
}
return searchInternal(JSON.parse(JSON.stringify(input)) /* create a working copy with JSON.parse(...) */);
}
console.log('master', search(m, 'master'));
console.log('xxx-master', search(m, 'xxx-master'));
console.log('m', search(m, 'm'));
console.log('bar', search(m, 'bar'));
console.log('slkvcsmcskc', search(m, 'slkvcsmcskc'));
Actually it should go like this:
obj = {
_id: "sjkd9skj",
data: {
dektop: [
{
x: 2,
y: 3,
t: { key: 'aabbcc'}
},
...
],
mobile: [
{
x: 4,
y: 3,
t: { key: 'ffff'}
},
...
],
print: [
{
x: 7,
y: 5,
t: { key: 'ppp'}
},
...
]
}
}

Categories