How to add a loop in JSON using angular - angularjs

I need to create a JSON structure like this:
"combinationsData":[
{
"combinationName":"2_2",
"dataGroups": [
{
"tableType":"2",//This value comes from HTML
"twoAxisData":[{
"vAxis":18,//This value also comes from HTML
"dataValue":[
{//Need to iterate the hAxis. I need to add a loop to iterate this value
"hAxis":"03",
"dataValue":"0.7750"
},{
"hAxis":"04",
"dataValue":"1.48"
},{
"hAxis":"05",
"dataValue":"1.48"
},{
.
.
.
"hAxis":"08",
"dataValue":"0.06833"
}
]
},
{
"vAxis":20,
"dataValue":[
{
"hAxis":"01",
"dataValue":"1.48"
},{
"hAxis":"02",
"dataValue":"1.48"
},{
"hAxis":"03",
"dataValue":"1.48"
},{
"hAxis":"04",
"dataValue":"1.48"
},{
"hAxis":"05",
"dataValue":"1.48"
},{
"hAxis":"06",
"dataValue":"1.48"
},{
"hAxis":"07",
"dataValue":"1.48"
}
]
}]
},
{
"tableType":"1",
"oneAxisData":[
{
"vAxis":"18",
"dataValue":"1.48"
},
{
"vAxis":"19",
"dataValue":"1.48"
},
{ "vAxis":"19",
"dataValue":"1.48"
}
]
}
]
},
]
}
This is my controller code, in which I am getting some values from HTML and based on the values I need to iterate a loop in JSON. I am not getting how to add a loop inside JSON as it is an object.
mapData = function() {
"combinationData": {
"combinationName": "2_2",
"dataGroups": {
"tableType": "2",
"twoAxisData": {
for (var i = 0; i < 5; i++) { //Need to add a loop like this to iterate till its value
"vAxis": $scope.vAxis,
"dataValue": {
"hAxis": "2",
"dataValue": $scope.hrows
},
}
}
}
Please suggest how to create a JSON structure using a iterative loop

mapData = function() {
var jsonData = {
"combinationData": {
"combinationName": "2_2",
"dataGroups": {
"tableType": "2",
"twoAxisData": []
}
}
}
for (var i = 0; i < 5; i++) {
jsonData["combinationData"]["dataGroups"]["twoAxisData"]
.push({
"vAxis": $scope.vAxis,
"dataValue": {
"hAxis": "2",
"dataValue": $scope.hrows
}
})
}
}

Related

From an array of objects, extract value of a property as array in angular

I have an array that looks like below:
[
{ "name":"ABC", "group":"A" },
{ "name":"XYZ", "group":"A" },
{ "name":"KLP", "group":"A" },
{ "name":"AKG", "group":"B" },
{ "name":"DIS", "group":"B" },
{ "name":"FAC", "group":"B" },
{ "name":"TAM", "group":"B" },
{ "name":"NEW", "group":"C" },
{ "name":"UTL", "group":"C" },
{ "name":"WAC", "group":"C" }
]
How can I sort this by group in angular
I want result like below
{
"A":[ "ABC", "XYZ", "KLP" ],
"B":[ "AKG", "DIS", "FAC", "TAM" ],
"C":[ "NEW", "UTL", "WAC" ]
}
Please help me to do so
Thanks in advance
const sortedData: any = {};
for (const d of this.data) {
sortedData[d.group] ? sortedData[d.group].push(d.name) : sortedData[d.group] = [d.name];
}

Update multiple object values inside array in MongoDB with different values without looping, but pure query

I want to update this document in MongoDB
[
{
"persons" : [
{
"name":"Javier",
"occupation":"teacher"
},
{
"name":"Juliana",
"occupation":"novelist"
},
{
"name":"Henry",
"occupation":"plumber"
}
]
}
]
let's say I have a global array variable that contains this
var peopleGlobalVar = [
{
"name":"Javier",
"occupation":"gardener"
},
{
"name":"Henry",
"occupation":"postman"
}
]
I want to update the document with the value in globalVar WITHOUT common javascript looping, so if the names match, the occupation value will change, and I'm looking for the "pure query" solution.
the code I expect:
collection.update(
{},
{
$set: {
// code ...
}
},
{
$arrayFilter: [
{
"elem.name": {
$in:
$function : {
body: function(updatedPeopleFromGlobalVariable){
let names = [];
updatedPeopleFromGlobalVariable.forEach(function(person){
names.push(person.name);
return names;
},
args: peopleGlobalVar,
lang:"js",
}
},
"multi": true
}
]
}
)
What the output should be
[
{
"persons" : [
{
"name":"Javier",
"occupation":"gardener"
},
{
"name":"Juliana",
"occupation":"novelist"
},
{
"name":"Henry",
"occupation":"postman"
}
]
}
]
Anyone have the solution to this?

Convert array of Objects into a grouped array of Objects Typescript

I'm trying to convert an array of objects like this:
[{grandParentField:'grandParent1', parentField:'parent1', childField: 'child1'},
{grandParentField:'grandParent1', parentField:'parent1', childField: 'child2'},
{grandParentField:'grandParent2', parentField:'parent1', childField: 'child3'},
{grandParentField:'grandParent2', parentField:'parent2', childField: 'child4'}]
into this form:
[
{
text: 'grandparent1',
items: [
{
text: 'parent1',
items: [{ text: 'child1' }, { text: 'child2' }]
}
]
},
{
text: 'grandparent2',
items: [
{
text: 'parent1',
items: [{ text: 'child3' }]
},
{
text: 'parent2',
items: [{ text: 'child4' }]
}
]
}
]
This Thread is similar to what I want, but not quite.
children will always be unique, but parents can have multiple grandparents.
Honestly I've tried so many things I'm not even sure which one to include as an example of what has gotten me closest.
Something like this but able to take in an array of Objects, and pump out the {text: string, items:[{text: string, items:[{text:string]]} structure:
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
console.log(groupBy(['one', 'two', 'three'], 'length'));
// => {3: ["one", "two"], 5: ["three"]}
Recursive approach, should work for every n-nested input that you will provide:
const input =[{grandParentField:"grandParent1",parentField:"parent1",childField:"child1"},{grandParentField:"grandParent1",parentField:"parent1",childField:"child2"},{grandParentField:"grandParent2",parentField:"parent1",childField:"child3"},{grandParentField:"grandParent2",parentField:"parent2",childField:"child4"}];
const nestedGroupBy = (nodes, order, orderIdx = 0) => {
const key = order[orderIdx]
let grouped = nodes.reduce((acc, e, i) => {
let node = acc.find(x => x.text == e[key])
if (!node) {
node = { text: e[key], items: [] }
acc.push(node)
}
node.items ? node.items.push(e) : node.items = [e]
return acc
}, [])
if (order[orderIdx + 1])
grouped = grouped.map(e => ({
text: e.text,
items: nestedGroupBy(e.items, order, orderIdx + 1)
}))
else
grouped = grouped.map(e => ({ text: e.text }) )
return grouped
}
const res = nestedGroupBy(input, Object.keys(input[0]))
console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Without getting too crazy with types, I'd say that you want your output to be of this shape:
interface Tree {
text: string,
items?: Tree[]
}
So let's make a function called group() which takes your array and a list of keys that you want to process in the order they should be processed. So for your example it would be used like this:
const data = [
{ grandParentField: 'grandParent1', parentField: 'parent1', childField: 'child1' },
{ grandParentField: 'grandParent1', parentField: 'parent1', childField: 'child2' },
{ grandParentField: 'grandParent2', parentField: 'parent1', childField: 'child3' },
{ grandParentField: 'grandParent2', parentField: 'parent2', childField: 'child4' }
];
const groupedData = group(data, "grandParentField", "parentField", "childField");
Here's the implementation of group():
function group(data: Array<Record<string, string>>, key: string, ...otherKeys: string[]): Tree[] {
const objMap: Record<string, any[]> = {}
for (const d of data) {
if (!(d[key] in objMap)) {
objMap[d[key]] = []
}
objMap[d[key]].push(d);
}
return Object.keys(objMap).map(k => otherKeys.length ?
{
text: k,
items: group(objMap[k], otherKeys[0], ...otherKeys.slice(1))
} : {
text: k
}
);
}
First we group the elements from data into a dictionary of arrays called objMap, where each element d goes into the key of objMap at d[key] (so the first element goes into the key named "grandParent1" if key is "grandParentField").
Once this grouping is done, we return a new array by walking through objMap's keys. If we have no otherKeys, we just return an array of {text: string} elements using the keys of objMap as the text field. If we do have other keys, then we need to recursively call group() on the elements stored in objMap at the proper key.
You can verify that this works for your example:
console.log(JSON.stringify(groupedData, undefined, 2));
/* [
{
"text": "grandParent1",
"items": [
{
"text": "parent1",
"items": [
{
"text": "child1"
},
{
"text": "child2"
}
]
}
]
},
{
"text": "grandParent2",
"items": [
{
"text": "parent1",
"items": [
{
"text": "child3"
}
]
},
{
"text": "parent2",
"items": [
{
"text": "child4"
}
]
}
]
}
] */
Playground link to code

how to use Immutability helper to update a nested object within an array?

Inside reducer, given a state object:
var state = {
"data": [{
"subset": [{
"id": 1
}, {
"id": 2
}]
}, {
"subset": [{
"id": 10
}, {
"id": 11
}, {
"id": 12
}]
}]
}
As you can see, the data is a nested array, with arrays in each of its elements.
Knowning that action.indexToUpdate will be a index for data, I want to update data[action.indexToUpdate].subset to a new array programmatically. For example, if action.indexToUpdate = 0, then data[0] will be updated from
[{"id":1},{"id":2}]
to
[{"id":4},{"id":5}]
In order to do so, I have:
let newSubset = [{"id":4},{"id":5}]
let newState = update(state.data[action.indexToUpdate], {
subset: {
newSubset,
},
})
But when I executed this, it returns error:
TypeError: value is undefined
on the update founction.
I have been looking at the react ducomentation here: https://facebook.github.io/react/docs/update.html but I couldn't really figure out how to do it. Please advise!
Your update will look like
var obj = {"state" : {
"data": [{
"subset": [{
"id": 1
}, {
"id": 2
}]
}, {
"subset": [{
"id": 10
}, {
"id": 11
}, {
"id": 12
}]
}]
}}
return update(obj, {
"state" : {
"data": {
[action.indexToUpdate]: {
"subset": {
$set: [newSubset]
}
}
}
}
})
In case there are other fields in subset, but you only wish to the change the fields at specific index containing other keys, you would write
return update(obj, {
"state" : {
"data": {
[action.indexToUpdate]: {
"subset": {
[id]: {$merge: newSubset}
}
}
}
}
})

Mongodb object within array within array

I'm having this JSON data structure:
{
data :
{
fields_data :
[
[
{
key1 : val
},
{
key1 : val
}
],
[
{
key2 : val
},
{
key2 : val
}
]
]
}
}
I'm having hard time to query this, I'd tried to use the in and the elemMatch in other ways but with no success.
one of the queries I've tried :
{
"data.fields_data": {
$in: [{
$in: [{
$elemMatch:
{
$elemMatch : {
"key1": "random text"
}
}
}]
}]
}
}
Any suggestions?
Well, nested $elemMatch should work here:
db.collection.find{
'data.fields_data': {
$elemMatch: {
$elemMatch: {
key1: val
}
}
}
}
But you should consider getting rid of nested array here. For example, you could use array if objects instead:
{
data: {
fields_data: [{
data: [
{ key1: val },
{ key1: val }
]}, {
data: [
{ key2: val },
{ key2: val }
]}
]
}
}
It will allow you to query your documents using simple dot notation:
{ 'data.fields_data.data.key1': val }

Resources