Combine 2 different javascript json objects into one with a loop and joining on the questionid , - javascript

So I am trying to combine 2 different javascript object than I can end up using in an angularjs ng-repeat . since there is a 1 to many relationship from the database, I was pulling queries separately.
What I have is this:
Main list of data , 3 object sample
0: Object
$$hashKey: "object:4"
Active:true
QuestionId:2
SalesChannel:"DTD"
1: Object
$$hashKey: "object:5"
Active:true
QuestionId:3
SalesChannel:"DTD"
2: Object
$$hashKey: "object:6"
Active:true
QuestionId:5
SalesChannel:"DTD"
Then another query returned data into what I want to relate as JSON into the other object
Object { Id: 3, Name: "Text box" QuestionId: 3}
{ Id: 4, Name: "Text box" QuestionId: 3}
{ Id: 9, Name: "Text box" QuestionId: 5}
So since I have both of these objects , I am wanting to combine.
Naturally I would think that I should return from the database, but then I also think about looping over and appending
for loop on main
{
.... find where main.QuestionId = sub.QuestionId and it to be added in as a nested object of json type...
Thus the end result SHOULD look like
[{
Active:true,
QuestionId: 3
SubData: [ {
Id: 3,
Name: "TextBox
QuestionId:3
},
{
Id: 4,
Name: "TextBox
QuestionId:3
}],
SalesChannel: "DTD"
}]
// and so on
How can i achieve this?

You want to go through all of the main objects, and assign to them only those results from second query. Use Array.prototype.forEach to go through them all, and Array.prototype.filter to select only appropriate results from secondary query.
firstQueryResult.forEach((firstObject)=>
firstObject.subdata = secondQueryResult.filter((secondObject)=>
secondObject.QuestionId === firstObject.QuestionId))
BTW, this has nothing to do with angularjs
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Related

Problem while filtering one array based on values in second array in Vue.js

I have a problem filtering the data array. I have two arrays: families and children. And I can't figure out how I could filter the array according to the age field in the children's array. I already translate:
The common thing between these data arrays is the family_id field.
My code looks like this:
filterProductsByYear: function(families) {
return families.filter(
family => family.family_id.includes(this.children.family_id)
);
},
And how could I filter a families array of data by the age of children array about the children_year field?
I wonder if adding a where clause in this includes make sense, I thought it was the best idea, but I don't know how can I do it.
You should provide an in and output example in your question, or we have to make many assumptions about the data structure. You could try the following. It returns all the families with at least one child under 18:
familiesWithAdolescentChildren: function(families, children) {
return families.filter(
family => children.some(
child => child.family_id == family.id && child.age > 18)
)
);
},
Example:
in:
familes: [{id: 1}, {id: 2}]
children: [{family_id: 1, age: 3}, {family_id: 1, age: 21}, {family_id: 2, age: 20}]
out:
[{id: 1}]

How to get second duplicate value rather than first value from JSON Array in React JS using lodash? [duplicate]

This question already has an answer here:
Lodash uniqBy update the latest value
(1 answer)
Closed 9 months ago.
I am working on one project where I need to remove duplicate values from JSON array object with some specification in react JS. I have tried to remove using _.uniqBy but in the output it took very first value from duplicate value which is I don't want.
Suppose You have an array JSON like:
[ { id: 1, name: 'bob' }, { id: 2, name: 'bill' }, { id: 1, name: 'alice' } ]
using _.uniqBy I got [ { id: 1, name: 'bob' }, { id: 2, name: 'bill' }] this output.
but I want [ { id: 2, name: 'bill' }, { id: 1, name: 'alice' } ] this output.
As you can see I want output whose name is alice not bob along with id:1.
Can anyone help me?
Thank you.
My first thought is to use a reduce, and shove the items in a map, then get the values:
Object.values(items.reduce((map, item) => ({ ...map, [item.id]: item }), {}))
This is probably not very efficient though if you're dealing with large arrays of have performance concerns.
It's a quick and dirty one-liner. If you want something more efficient I'd take a look at the lodash source code and tweak it to your needs or write something similar:
https://github.com/lodash/lodash/blob/2f79053d7bc7c9c9561a30dda202b3dcd2b72b90/.internal/baseUniq.js

Sequelize.js get orders divided by the status

I have a Node.JS project and am using sequelize as the ORM.
I would like to run a query where I get all of my orders grouped by the status. So I would get for example an object with 5 keys (given that I have 5 different statuses). And in each key there would be an array with all orders that have that status.
Example of object:
{
"Done": [{id:1, item: "bag"}, {id:2, item: "purse"}],
"Processing": [{id:3, item: "bag"}, {id:4, item: "purse"}],
"Pending": [{id:5, item: "bag"}, {id:6, item: "purse"}]
}
Is this possible in any way or I need to get all possible statuses and just run the same number of queries each time changing the where clause?
Thanks
.findAll() gives you back a result set consisting of an array of model instances. I guess in your case it will be an array of Orders. It's flattened, not hierarchical.
That will look something like this.
[
{status: "Done", id:1, item: "bag"},
{status: "Done", id:2, item: "purse"},
{status: "Processing", id:3, item: "bag"},
{status: "Processing", id:4, item: "purse"},
{status: "Pending", id:5, item: "bag"},
{status: "Pending", id:6, item: "purse"}
]
You can then turn that flattened result set into the hierarchical one you want. Something like this, not debugged, should do the job.
const byStatus = {}
for (const row of resultSet) {
/* first time we've seen this status value? if so create an array for it. */
if (!byStatus[row.status]) byStatus[row.status] = []
/* put the present row into the appropriate array */
byStatus[row.status].push( {id: row.id, item: row.item })
}
That way you can run just one .findAll() query. That's a good idea because it's more efficient than running multiple ones.
You need to use a "native" query with a GROUP BY clause or you fetch the data normally and do the gruoping in JS/TS using lodash's groupBy.

Javascript Map a Collection

The Issue:
I'm attempting to build a simple search tool. It returns a search query by matching an id to another item with the same id. Without going into the complexities, the issue I'm having is that when my data was organized previously, the map function from javascript returned all the results perfectly. However, now that my data is structured a bit differently (a collection, I think?) ....the ids don't appear to be lining up which causes the wrong search results to show.
The function in question:
const options = this.props.itemIds.map((id) => (
<Option key={this.props.itemSearchList[id].id}>
{this.props.itemSearchList[id].name}
</Option>
));
When the data was structured like this it worked as expected:
Example of previous structure:
const items = [
{
id: 0,
name: "name 0",
tags: ['#sports', '#outdoor', '#clothing'],
},
{
id: 1,
name: "name 1",
tags: ['#sports', '#outdoor', '#clothing'],
},
{
id: 2,
name: "Name 2",
tags: ['#sports', '#outdoor', '#clothing'],
},
Now that the data is a ?collection...the map function doesn't work as anticipated and it returns improper results or none at all: I've been able to use the lodash Map function on this structure successfully in the past.
Here's a screenshot of the new data:
I believe a representative way to write out the example would be:
const newItems = [
0: {
id: 0,
name: "name here",
},
1: {
id: 1,
name: "name here",
},
]
Any recommendations for making this work or need more info? Perhaps I'm misunderstanding the issue entirely, but I believe it has to do with data structure and the map function from JS. I can see results returning, but the id's are not lining up appropriately anymore.
Here's a visual representation of the misalignment. The orange is the search input and it pulling the right result. The green is the misalignment of what it's actually showing because of the data structure and mapping (I assume).
The issue is you were using index and lining that up with id as a sort of pseudo-key which is...beyond fragile. What you should be doing is keying by id (meaing itemsshould be an object) and then having a seperate array that stores the order you want. So items would be an object keyed by id:
const items = {
1: {
id: 1,
name: "name 1",
tags: ['#sports', '#outdoor', '#clothing'],
},
2: {
id: 2,
name: "name 2",
tags: ['#sports', '#outdoor', '#clothing'],
},
9: {
id: 9,
name: "Name 9",
tags: ['#sports', '#outdoor', '#clothing'],
},
};
And then itemIds (which it appears you already have) is an array with the correct order:
const itemIds = [1,9,2];
And then they can be accessed in the right order by looping over that array, and getting the element by said key:
itemIds.map((id) => {
const item = items[id];
// do something with the item
}
Take a look at how Redux recommends normalizing state shape.
https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape
What you call "collections" and "maps" are actually arrays. Now one of the arrays has the objects exactly at the position in the array that matches the id:
items[5].id === 5
Now through sorting /mutating / whatever you change the order so that the element at a certain position doesnt have that as an id:
newItems[5].id // 7 :(
That means that you cannot access the item that easy anymore, you now either have to sort the array again to bring it into order, or you search for an object with the id:
newItems.find(item => item.id === 5) // { id: 5, ... }
Or you switch over to some unsorted collections like a real Map:
const itemsMap = new Map(newItems.map(item => ([item.id, item])));
So you can get a certain item with its id as:
itemsMap.get(5) // { id: 5, ... }
... but the whole thing doesnt have to do with Array.prototype.map at all.
Here was my simple solution:
const options = [];
this.props.itemList.forEach((item) => {
if (this.props.searchResults.includes(item.id)) {
options.push(<Option key={item.id}>{item.name}</Option>);
}
});
Let me know what you think (to the group that tried to help!)

How to reference a specific object in an array of objects using jTemplates

I am using the excellent jTemplates plugin to generate content.
Given a data object like this...
var data = {
name: 'datatable',
table: [
{id: 1, name: 'Anne'},
{id: 2, name: 'Amelie'},
{id: 3, name: 'Polly'},
{id: 4, name: 'Alice'},
{id: 5, name: 'Martha'}
]
};
..I'm wondering if it is possible to directly specify an object in an array of objects using $T. (I'm hoping there is something like $T.table:3 available)
Currently the only way I can think of to access a specific object in an array is to do something like this...
{#foreach $T.table as record}
{#if $T.record$iteration == 3}
This is record 3! Name: {$T.record.name}
{#/if}
{#/for}
However that seems clumsy...
Any suggestions?
Thanks
With the data you posted, you can do this with plain javascript :)
data.table[2].id // 3
data.table[2].name // "Polly"
table is an immediate child of data, and this gets it's third child (arrays are 0 based).
The alternative, if I misunderstood and you want to search by id, would be something like this:
for(var i in data.table) {
var o = data.table[i];
if(o.id == 3) alert(o.name); // "Polly"
}

Categories

Resources