How can I get the values of the products array inside of an array. I want to combine the products array?
data = [
{
"id": "ORDER-111",
"products": [
{
"id": "5435",
"productName": "Banana",
}
],
},
{
"id": "ORDER-222",
"products": [
{
"id": "75434",
"productName": "Apple",
},
{
"id": "5345",
"productName": "Mango",
}
],
}
]
EXPECTED OUTPUT
"products": [
{
"id": "5435",
"productName": "Banana",
},
{
"id": "75434",
"productName": "Apple",
},
{
"id": "5345",
"productName": "Mango",
}
],
CODE
console.log(
...data
.reduce((r, { products }) => {
(products || []).forEach((o) => {
r.has(o.id);
});
return r;
}, new Map())
.values()
);
This would be a good place to use .flatMap - in the callback, just navigate to the products subarray of each object:
const data = [
{
"id": "ORDER-111",
"products": [
{
"id": "5435",
"productName": "Banana",
}
],
},
{
"id": "ORDER-222",
"products": [
{
"id": "75434",
"productName": "Apple",
},
{
"id": "5345",
"productName": "Mango",
}
],
}
];
const result = data.flatMap(obj => obj.products);
console.log(result);
In older environments without flatMap, use a polyfill or spread into concat instead:
const data = [
{
"id": "ORDER-111",
"products": [
{
"id": "5435",
"productName": "Banana",
}
],
},
{
"id": "ORDER-222",
"products": [
{
"id": "75434",
"productName": "Apple",
},
{
"id": "5345",
"productName": "Mango",
}
],
}
];
const result = [].concat(...data.map(obj => obj.products));
console.log(result);
Related
I have the following array
[ {
"contactId": "a87d096gd5fuop",
"firstName": "John Doe",
"registrationTypes": {
"selectedOptions": [
{
}
],
"subTotal": 1620.003
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"events": {
"selectedOptions": [
{
"id": "1",
"name": "T1",
"value": "4550006:3",
},
{
"id": "2",
"name": "T2",
"value": "4550005:3",
},
{
"id": "3",
"name": "T3",
"value": "4550003:3",
}
],
"subTotal": 135.003
},
"freeNetworkingFunctions": {
},
"total": 1755.0059999999999
},
{
"contactId": "a097f",
"firstName": "David",
"registrationTypes": {
"selectedOptions": [
{}
],
"subTotal": 899.998
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"member": {
"selectedOptions": [
{
}
],
"subTotal": 228.8
},
"events": {
"selectedOptions": [
{
"id": "4",
"name": "T4",
"value": "4550002:2",
},
{
"id": "5",
"name": "T5",
"value": "4550001:2",
},
{
"id": "6",
"name": "T6",
"value": "4550003:2",
}
],
"subTotal": 135.003
},
"total": 1263.801
}
]
From the above array, I want to extract events, loop all the data and get only values. So my new array should be something like this:
[ {
"contactId": "a87d096gd5fuop",
"firstName": "John Doe",
"registrationTypes": {
"selectedOptions": [
{
}
],
"subTotal": 1620.003
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"events": [
"4550006:3"
"4550005:3",
"4550003:3",
],
},
"freeNetworkingFunctions": {
},
"total": 1755.0059999999999
},
{
"contactId": "a097f",
"firstName": "David",
"registrationTypes": {
"selectedOptions": [
{}
],
"subTotal": 899.998
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"member": {
"selectedOptions": [
{
}
],
"subTotal": 228.8
},
"events": [
"4550004:2"
"4550008:3",
"4550003:3",
],
"subTotal": 135.003
},
"total": 1263.801
}
]
So it should return the original array, however, events value data should be in one array.
var arr = [];
var r(var i=0;i<data.length;i++){
data.push(arr[i].value);
}
var newData = [...data, arr]
However, this doesn't work. Any help would be highly appreciated.
Use map twice - once on the dataset to iterate over the objects, and within that map to get an array of values from the selectedOptions.
const data=[{contactId:"a87d096gd5fuop",firstName:"John Doe",registrationTypes:{selectedOptions:[{}],subTotal:1620.003},foo1:{selectedOptions:[],subTotal:0},events:{selectedOptions:[{id:"1",name:"T1",value:"4550006:3"},{id:"2",name:"T2",value:"4550005:3"},{id:"3",name:"T3",value:"4550003:3"}],subTotal:135.003},freeNetworkingFunctions:{},total:1755.0059999999999},{contactId:"a097f",firstName:"David",registrationTypes:{selectedOptions:[{}],subTotal:899.998},foo1:{selectedOptions:[],subTotal:0},member:{selectedOptions:[{}],subTotal:228.8},events:{selectedOptions:[{id:"4",name:"T4",value:"4550002:2"},{id:"5",name:"T5",value:"4550001:2"},{id:"6",name:"T6",value:"4550003:2"}],subTotal:135.003},total:1263.801}];
const out = data.map(obj => {
// Destructure the selected options from the
// rest of each object
const { events: { selectedOptions }, ...rest } = obj;
// `map` over the options to just get an array of values
const events = selectedOptions.map(option => {
return option.value;
});
// Return a new object with the new events property
// combined with the other properties again
return { ...rest, events };
});
console.log(out);
Additional documentation
Destructuring assignment
Rest parameters
Spread syntax
I need to group the array with a nested value type.Id. How to change the current groupby function to achieve this.
Current function will group using the productName or Price. Need to group using a nested value type.id
Any help would be greatly appreciated!
Group by function
static groupBy<T>(data: T[], key: string): T[] {
return <T[]>data.reduce((a, b) => {
(a[b[key]] = a[b[key]] || []).push(x);
return <T[]>a;
}, {});
}
sample value:
var sales = [
{
"productName": "AAA",
"type": {
"id": 1,
"name": "Soap"
},
"price": 90
},
{
"productName": "BBB",
"type": {
"id": 1,
"name": "Soap"
},
"price": 85
},
{
"productName": "CCC",
"type": {
"id": 1,
"name": "Soap"
},
"price": 55
},
{
"productName": "DDD",
"type": {
"id": 2,
"name": "shampoo"
},
"price": 2
},
{
"productName": "EEE",
"type": {
"id": 2,
"name": "shampoo"
},
"price": 5
}
]
Expected Result:
{1},
[
{
"productName": "AAA",
"type": {
"id": 1,
"name": "Soap"
},
"price": 90
},
{
"productName": "BBB",
"type": {
"id": 1,
"name": "Soap"
},
"price": 85
},
{
"productName": "CCC",
"type": {
"id": 1,
"name": "Soap"
},
"price": 55
}],
{2},[
{
"productName": "DDD",
"type": {
"id": 2,
"name": "shampoo"
},
"price": 2
},
{
"productName": "EEE",
"type": {
"id": 2,
"name": "shampoo"
},
"price": 5
}
]
Add an accessor function to use properties at any depth,
function groupBy<T>(data: T[], key: string): T[] {
const path: string[] = key.split('.');
const accessor = (obj: T) => path.reduce((x,y) => x[y], obj)
return <T[]>data.reduce((a, b) => {
const value = accessor(b).toString();
(a[value] = a[value] || []).push(b);
return <T[]>a;
}, {});
}
console.log(groupBy(sales, 'type.id'))
Runnable JS version
const sales = [
{
"productName": "AAA",
"type": {
"id": 1,
"name": "Soap"
},
"price": 90
},
{
"productName": "BBB",
"type": {
"id": 1,
"name": "Soap"
},
"price": 85
},
{
"productName": "CCC",
"type": {
"id": 1,
"name": "Soap"
},
"price": 55
},
{
"productName": "DDD",
"type": {
"id": 2,
"name": "shampoo"
},
"price": 2
},
{
"productName": "EEE",
"type": {
"id": 2,
"name": "shampoo"
},
"price": 5
}
]
function groupBy(data, key) {
const path = key.split('.');
const accessor = (obj) => {
return path.reduce((x,y) => {
return x[y]
}, obj).toString();
}
return data.reduce((a, b) => {
const prop = accessor(b);
(a[prop] = a[prop] || []).push(b);
//a[prop] = a[prop] || [];
//a[prop].push(b);
return a;
}, {});
}
console.log(groupBy(sales, 'type.id'))
I would like to simplify this nested array of objects move some items at the top level with a new property name. Given this data:
let data = [
{
"id": 1001,
"model": "Lemon",
"length": "4",
"details": [
{
"id": 38,
"kind": "D",
"color": "Gray",
"specifics": {
"id": 3
}
}
]
},
{
"id": 1002,
"model": "Botanica",
"length": "2",
"details": [
{
"id": 39,
"kind": "A",
"color": "Yellow",
"specifics": {
"id": 1
}
},
{
"id": 40,
"kind": "B",
"color": "Green",
"specifics": {
"id": 2
}
},
]
}
];
My desired output:
[
{
"id": 3,
"model": "Lemon",
"color": "Gray",
},
{
"id": 1,
"model": "Botanica",
"color": "Yellow",
},
{
"id": 2,
"model": "Botanica",
"color": "Green",
}
]
Or much better to combine the model and color:
[
{
"id": 3,
"model": "Lemon - Gray"
},
{
"id": 1,
"model": "Botanica - Yellow"
},
{
"id": 2,
"model": "Botanica - Green"
}
]
If there are multiple specifics, it would also create a new object together with the model and color, then it would move at the top. Here's what I've tried so far:
const result = data.map(({ details, ...d }) => ({
...d,
data: details.map(({ specifics, ...s }) => ({
...r,
id: specifics.id
}))
}));
But it seems that I can't get the right result. How to simplify this one? Thanks.
First, we need to loop through the data array. We can get the model from the data element namely item. Then we need to loop through that item.details array. From that we can get id, detail.color. Hers's the full code.
let data = [
{
"id": 1001,
"model": "Lemon",
"length": "4",
"details": [
{
"id": 38,
"kind": "D",
"color": "Gray",
"specifics": {
"id": 3
}
}
]
},
{
"id": 1002,
"model": "Botanica",
"length": "2",
"details": [
{
"id": 39,
"kind": "A",
"color": "Yellow",
"specifics": {
"id": 1
}
},
{
"id": 40,
"kind": "B",
"color": "Green",
"specifics": {
"id": 2
}
},
]
}
];
const result = data.reduce((result, item) => {
return [...result, ...item.details.map((detail) => {
return {
id: detail.specifics.id,
model: item.model + " - " + detail.color
}
} )]
}, []);
console.log(result);
I have the following nested array of objects:
[
{
"info": [
{
"period": {
"start": "2020-01-01",
"end": "2020-01-31"
},
"info": [
{
"id": 036,
"name": "john",
},
{
"id": 037,
"name": "inna",
}
]
}
]
},
{
"info": [
{
"period": {
"start": "2020-01-01",
"end": "2020-01-31"
},
"info": [
{
"id": 045,
"name": "carl",
},
{
"id": 056,
"name": "tina",
}
]
}
]
}]
I want to extract all the values of the "name" property and put them in an array.
Output: ["john", "inna", "carl", "tina"].
Try with this code:
const userNames = [];
data.map(item => {
return item.info.map(registry => {
return registry.info.map(user => userNames.push(user.name));
})
})
Output: ["john", "inna", "carl", "tina"]
I am trying to figure out how to group by at multiple levels:
Given the following input JSON:
[
{
"GroupingMajor": "Fruit",
"Grouping": "Banana",
"Description": "10 Bananas",
"Price": 20609.82,
},
{
"GroupingMajor": "Fruit",
"Grouping": "Apple",
"Description": "13 Apples",
"Price": 4567.98,
},
{
"GroupingMajor": "Dairy",
"Grouping": "Cheese",
"Description": "1 KG",
"Price": 76456.76,
}
]
I would like to create output of type:
{
"name": "root",
"children": [
{
"name": "Fruit",
"children": [
{
{"name": "Apple", "price": 4567.98},
{"name": "Banana", "price": 20609.82}
}]
},
{
"name": "Dairy",
"children": [
{
{"name": "Cheese", "price": 76456.76}
}]
}]
}
That is, data is grouped by "GroupingMajor" and then "Grouping". "Grouping" being a child of the parent "GroupingMajor" category. How can I generate this output using linq.js (JavaScript)?
Here is some JavaScript that I've attempted:
var data = Enumerable.From(dataFood)
.GroupBy(
function (e) {
return {
groupmajor: e.GroupingMajor,
groupminor: e.Grouping
}},
function (e) {
return {
groupmajor: e.GroupingMajor,
groupminor: e.Grouping,
name: e.GroupingMajor,
price: e.Price,
}
},
function (key, g) {
return {
group: key.groupmajor,
groupminor: key.groupminor,
name: g.name,
price: g.price
}
})
.ToArray();
I am not getting a correct grouping and I have no idea how to generate a sub-group.
Any help is appreciated.
Here's how you could construct such a query:
var query = Enumerable.From(data)
.GroupBy(
"$.GroupingMajor", // key
"{ name: $.Grouping, price: $.Price }", // item
"{ name: $, children: $$.ToArray() }" // result
)
.ToArray();
var result = {
name: 'root',
children: query
};
Which would yield the following result:
{
"name": "root",
"children": [
{
"name": "Fruit",
"children": [
{
"name": "Banana",
"price": 20609.82
},
{
"name": "Apple",
"price": 4567.98
}
]
},
{
"name": "Dairy",
"children": [
{
"name": "Cheese",
"price": 76456.76
}
]
}
]
}