How can i make two objects out of one object, dividing them by a value in the object with lodash - arrays

Consider this object, with two channels with NL language and one with EN language:
[
{
"name": "De Redactie",
"channels": [
{
"name": "headlines",
"pubDate": "2017-05-15 09:15:00",
"language": "nl",
"items": [
]
},
{
"name": "headlines English",
"pubDate": "2017-05-14 18:05:00",
"language": "en",
"items": [
]
},
{
"name": "politiek",
"pubDate": "2017-05-14 20:11:00",
"language": "nl",
"items": [
]
}
]
}
]
How can i divide them so that i can get this result:
[
{
"name": "De Redactie",
"channels": [
{
"name": "headlines",
"pubDate": "2017-05-15 09:15:00",
"language": "nl",
"items": [
]
},
{
"name": "politiek",
"pubDate": "2017-05-14 20:11:00",
"language": "nl",
"items": [
]
}
]
}
{
"name": "De Redactie",
"channels": [
{
"name": "headlines English",
"pubDate": "2017-05-14 18:05:00",
"language": "en",
"items": [
]
}
]
}
]
Mind you that this is dummyData. The actual data can contain x amount of one language and y amount of the second or third or fourth ...
I have tried looking in the lodash documentation for the correct combination of functions. Also tried various complex forEach structures, but could not wrap my head around it.
Preferably a solution with lodash or typescript, as i'm working in Angular 4.

Iterate the array with Array#map. For each object, extract the array of channels using destructuring with object rest. Iterate the channels using Array#reduce and group channels with the same language to a Map. Convert back to an array by spreading the Map's values iterator.
Create an array of objects, by mapping them and assigning the group as the channels prop of the object. Flatten the array by spreading into Array#concat:
const data = [{"name":"De Redactie","channels":[{"name":"headlines","pubDate":"2017-05-15 09:15:00","language":"nl","items":[]},{"name":"headlines English","pubDate":"2017-05-14 18:05:00","language":"en","items":[]},{"name":"politiek","pubDate":"2017-05-14 20:11:00","language":"nl","items":[]}]}];
const result = [].concat(...data.map(({ channels, ...rest }) => {
const channelGroups = [...channels.reduce((m, channel) => {
m.has(channel.language) || m.set(channel.language, []);
m.get(channel.language).push(channel);
return m;
}, new Map()).values()];
return channelGroups.map((channels) => ({
...rest,
channels
}));
}));
console.log(result);

way with lodash:
const res = _.chain(arr)
.flatMap(item => _.map( // get array of channels with parent name
item.channels,
channel => _.assign({}, channel, { parentName: item.name })
))
.groupBy('language') // group channels by language
.values() // get channel arrays for each lang
.map(langArrs => ({ // set finished structure
name: _.first(langArrs).parentName, // get name for lang channels
channels: _.omit(langArrs, ['parentName']) // set channels without parent name
}))
.value();

Related

How to filter JSON data based on another JSON data in typescript

I have 2 JSON Data 1. Payers 2. Rules. I need to filter Payers JSON data based on PayerId from Rules JSON data.
{
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "23456",
"name": "Test Payer2",
},
{
"payerId": "34567",
"name": "Test Payer3"
}}
Rules JSON file
{
"Rules": [
{
"actions": {
"canCopyRule": true
},
"RuleId": 123,
"description": "Test Rule",
"isDisabled": false,
"Criteria": [
{
"autoSecondaryCriteriaId": 8888,
"criteriaType": { "code": "primaryPayer", "value": "Primary Payer" },
"payerId": ["12345", "34567"]
}
]
}
}]}
I need to filter Payers JSON data based on Rules JSON data if PayerID matches
I need output like below
{
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "34567",
"name": "Test Payer3"
}
}
How to filter?
You can use Array.filter like that (based on your data structure):
const filteredPayers = payersObj.Payers.filter((p) => rulesObj.Rules[0].Criteria[0].payerId.includes(p.payerId));
I can't figure out why your Rules json looks like this, I guess you have multiple rules. If so, you will need to iterate over each rule and invoke includes. Same for Criteria.
Code will check each rule and each critirias
and will return payers if payerId found in any of the given rules of any criteria
const payers = {
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "23456",
"name": "Test Payer2",
},
{
"payerId": "34567",
"name": "Test Payer3"
}]}
const rules = {
"Rules": [
{
"actions": {
"canCopyRule": true
},
"RuleId": 123,
"description": "Test Rule",
"isDisabled": false,
"Criteria": [
{
"autoSecondaryCriteriaId": 8888,
"criteriaType": { "code": "primaryPayer", "value": "Primary Payer" },
"payerId": ["12345", "34567"]
}
]
}
]
}
const data = payers.Payers.filter(payer => rules.Rules.findIndex(rule => rule.Criteria.findIndex(criteria => criteria.payerId.includes(payer.payerId)) != -1) !== -1)
console.log(data)

Is it possible to get key value pairs from snowflake api instead rowType?

I'm working with an API from snowflake and to deal with the json data, I would need to receive data as key-value paired instead of rowType.
I've been searching for results but haven't found any
e.g. A table user with name and email attributes
Name
Email
Kelly
kelly#email.com
Fisher
fisher#email.com
I would request this body:
{
"statement": "SELECT * FROM user",
"timeout": 60,
"database": "DEV",
"schema": "PLACE",
"warehouse": "WH",
"role": "DEV_READER",
"bindings": {
"1": {
"type": "FIXED",
"value": "123"
}
}
}
The results would come like:
{
"resultSetMetaData": {
...
"rowType": [
{ "name": "Name",
...},
{ "name": "Email",
...}
],
},
"data": [
[
"Kelly",
"kelly#email.com"
],
[
"Fisher",
"fisher#email.com"
]
]
}
And the results needed would be:
{
"resultSetMetaData": {
...
"data": [
[
"Name":"Kelly",
"Email":"kelly#email.com"
],
[
"Name":"Fisher",
"Email":"fisher#email.com"
]
]
}
Thank you for any inputs
The output is not valid JSON, but the return can arrive in a slightly different format:
{
"resultSetMetaData": {
...
"data":
[
{
"Name": "Kelly",
"Email": "kelly#email.com"
},
{
"Name": "Fisher",
"Email": "fisher#email.com"
}
]
}
}
To get the API to send it that way, you can change the SQL from select * to:
select object_construct(*) as KVP from "USER";
You can also specify the names of the keys using:
select object_construct('NAME', "NAME", 'EMAIL', EMAIL) from "USER";
The object_construct function takes an arbitrary number of parameters, as long as they're even, so:
object_construct('KEY1', VALUE1, 'KEY2', VALUE2, <'KEY_N'>, <VALUE_N>)

Return document where array element includes all values of input array | MongoDB

I have a collection of exercises:
[
{
"name": "Push Ups",
"muscleGroups": ["Chest", "Shoulders", "Abs", "Biceps"]
},
{
"name": "Sit Ups",
"muscleGroups": ["Abs"]
},
{
"name": "Pull Ups",
"muscleGroups": ["Abs", "Biceps", "Back"]
}
]
and an input array of inputMuscleGroups. I am trying to filter the exercises to where the muscleGroups array of the document has every element of the inputMuscleGroups.
For inputMuscleGroups = ["Abs"], every document would return.
For inputMuscleGroups = ["Abs", "Biceps"], output would be:
[
{
"name": "Push Ups",
"muscleGroups": ["Chest", "Shoulders", "Abs", "Biceps"]
},
{
"name": "Pull Ups",
"muscleGroups": ["Abs", "Biceps", "Back"]
}
]
For inputMuscleGroups = ["Abs", "Shoulders", "Chest"], output would be:
[
{
"name": "Push Ups",
"muscleGroups": ["Chest", "Shoulders", "Abs", "Biceps"]
}
]
I have played around with $in but it appears these only return true if any of the input arrays match any of the document array.
Ideally I would want to do this within a .find() method as opposed to a .aggregate() method.
You can simply use $all
db.collection.find({
muscleGroups: {
$all: [
"Abs",
"Biceps"
]
}
})
Working Mongo playground

How can i filter the un matched array elements alone when compare with another array objects in angular 8

I have a two array response and I would like to compare the two responses and have to filter the unmatched array elements into a new array object.
Condition to compare the two response and filter is: we have to filter when code and number are not matched exactly with the response two then we have to filter such an array element into a new array object which I need as an output.
The Array element present in the Response two example is also present in the Response of Array One example which I don't want and I need to filter the array elements which is not matched with the Response of Array One.
Final Output which we filtered from the response two array will be like below which is unmatched with the response 1 array object:
{
"unmatchedArrayRes": [
{
"code": "08",
"number": "2323232323",
"id": "432",
"value": "value432"
}
]
}
Response of Array One
{
"MainData": [
{
"DataResponseOne": [
{
"viewData": {
"number": "11111111111111",
"code": "01"
},
"name": "viewDataOne"
},
{
"viewData": {
"number": "22222222222222",
"code": "01"
},
"name": "viewDataTwo"
},
{
"viewData": {
"number": "3333333333333",
"code": "02"
},
"name": "viewDataThree"
}
]
},
{
"DataResponseTwo": [
{
"viewData": {
"number": "5555555555555",
"code": "9090"
},
"name": "viewDataFour"
},
{
"viewData": {
"number": "6666666666666",
"code": "01"
},
"name": "viewDataFive"
},
{
"viewData": {
"number": "8888888888888",
"code": "01"
},
"name": "viewDataSix"
}
]
}
]
}
Response Two Example :
{
"compareRes": [
{
"code": "01",
"number": "11111111111111",
"id": "123",
"value": "value123"
},
{
"code": "9090",
"number": "5555555555555",
"id": "345",
"value": "value567"
},
{
"code": "08",
"number": "2323232323",
"id": "432",
"value": "value432"
}
],
"metaData": "343434343434"
}
First, create a combined list of all the view items from response one.
const combinedList = [];
res1["MainData"].forEach(data => {
// console.log(data);
for( let key in data) {
// console.log(key);
data[key].forEach(innerData => {
console.log(innerData)
combinedList.push(innerData["viewData"]);
})
}
});
In the above method, It is done in such a way that it can handle multiple viewData responses like DataResponseOne, DataResponseTwo, and so on.
And then filter second response Items like this:
const unfilteredListItems = res2["compareRes"].filter(data => {
return !combinedList.some(listItem => {
return listItem.code === data.code && listItem.number === data.number;
});
});
console.log(unfilteredListItems);
Working Stackblitz link: https://stackblitz.com/edit/ngx-translate-example-aq1eik?file=src%2Fapp%2Fapp.component.html

Find custom point coordinates with Forge

I work with Autodesk Forge (node.js, javascript (worked with it a little), React (completely new !)).
I have a rectangle 3D object. At each corner is a point with real world coordinates (lat, lon, z).
These coordinates can be displayed with the property panel in the viewer.
I want to access them from the code, but I cannot find them anywhere.
At first, I thought they would be at :
window.NOP_VIEWER.model.getData().metadata
but nothing !
Here is a picture of what I can see in the viewer. Since I can see them in the property panel, I should be able to access them !
I tried to use this :
window.NOP_VIEWER.model.getBulkProperties('1',
function(properties){console.log(properties);},
function(error){console.log(error);})
It returns an amazingly long list of field names (if think that's it).
When I try to put it in a variable it returns 'undefined'. So I cannot access what is inside anyway.
Also tried getProperties() but I think I did not write it in the right way, it doesn't work either.
I also tried som GET request to find the object properties, but all I got was this :
{
"data": {
"type": "objects",
"objects": [
{
"objectid": 1,
"name": "Model",
"objects": [
{
"objectid": 2691,
"name": "Sols",
"objects": [
{
"objectid": 2692,
"name": "Sol",
"objects": [
{
"objectid": 2693,
"name": "Dalle en béton - 250 mm",
"objects": [
{
"objectid": 2694,
"name": "Sol [236041]"
}
]
}
]
}
]
},
{
"objectid": 2711,
"name": "Modèles génériques",
"objects": [
{
"objectid": 2712,
"name": "Point_Georeferencement",
"objects": [
{
"objectid": 2713,
"name": "Point_Georeferencement",
"objects": [
{
"objectid": 2714,
"name": "Point_Georeferencement [236831]"
},
{
"objectid": 2715,
"name": "Point_Georeferencement [236836]"
},
{
"objectid": 2716,
"name": "Point_Georeferencement [236843]"
},
{
"objectid": 2717,
"name": "Point_Georeferencement [236846]"
}
]
}
]
}
]
}
]
}
]
}
}
But I cannot find a way to access the points' names or their values !
Can anyone help with this, please ?
NOP_VIEWER is a global variable to access the current Viewer. From that you can call:
.getProperties(): this requires 1 dbId, an easy way to try it is with:
NOP_VIEWER.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, function (e) {
e.dbIdArray.forEach(function (dbId) {
NOP_VIEWER.getProperty(dbId, function (props) {
console.log(props)
})
})
});
.model.getBulkProperties(): this received an array of elements and just return the properties you specify:
NOP_VIEWER.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, function (e) {
viewer.model.getBulkProperties(e.dbIdArray, ['RefX', 'RefY'], function (elements) {
elements.forEach(function(element){
console.log(element);
})
})
});
And you may also combine it with .search() (see here) or by enumerating leaf nodes.

Resources