I'm trying to loop thru products array and find its description in description array. The product id and description parent represent the same product. If the description could be found, push the product with its description to the results array.
I don't really know how this loop should look like.
Products
let products = [
{
"id": "43",
"titel": "Phone",
"price": "211"
},{
"id": "76",
"titel": "Battery",
"price": "34"
},{
"id": "102",
"titel": "Pen",
"price": "45"
},{
"id": "127",
"titel": "Apple",
"price": "10"
}
]
Descriptions
let descriptions= [
{
"description": "Good battery",
"parent": "76"
},{
"description": "Sharp pen",
"parent": "102"
},
]
Expected output results
let results = [
{
"id": "76",
"titel": "Battery",
"price": "34"
"description": "Good battery",
"parent": "76"
},{
"id": "102",
"titel": "Pen",
"price": "45"
"description": "Sharp pen",
"parent": "102"
},
]
You can take advantage of Array.prototype.reduce which allows to transform an array to another type of Object of array.
combine with the Array.prototype.find to check if item with a given id exists in the descriptions Array
let products = [
{
"id": "43",
"titel": "Phone",
"price": "211"
},{
"id": "76",
"titel": "Battery",
"price": "34"
},{
"id": "102",
"titel": "Pen",
"price": "45"
},{
"id": "127",
"titel": "Apple",
"price": "10"
}
]
let descriptions= [
{
"description": "Good battery",
"parent": "76"
},{
"description": "Sharp pen",
"parent": "102"
},
]
const result = products.reduce((acc, item) => {
// Check if the description of the current product exists
let exist = descriptions.find(desc => {
return item.id === desc.parent;
});
if(exist) {
return acc.concat({...item, description: exist.description});
}
return acc;
}, []);
console.log(result);
If you add another array comments you can update the code instead of to concatenate the item in the accumulator directly you'll create another object which after finding the related comment in the comment array you'll add the comment key in that object with their comment.
Here is the code
let products = [
{
"id": "43",
"titel": "Phone",
"price": "211"
},{
"id": "76",
"titel": "Battery",
"price": "34"
},{
"id": "102",
"titel": "Pen",
"price": "45"
},{
"id": "127",
"titel": "Apple",
"price": "10"
}
]
let descriptions= [
{
"description": "Good battery",
"parent": "76"
},{
"description": "Sharp pen",
"parent": "102"
},
]
let comments = [
{
"comment": "Good battery comment",
"product": "76",
}, {
"comment": "Sharp pen comment",
"product": "102"
}
];
const result = products.reduce((acc, item) => {
// Check if the description of the current product exists
let productExists = descriptions.find(desc => {
return item.id === desc.parent;
});
let commentExists = comments.find(comment => {
return item.id === comment.product
});
let newItem = null;
if(productExists) {
newItem = {
...item,
description: productExists.description
};
}
if(commentExists) {
newItem.comment = commentExists.comment;
}
return newItem? acc.concat(newItem): acc;
}, []);
console.log(result);
You should iterate over the descriptions, then use there Array.find and merge them together into a new object, with Object.assign and push them to your results
let products = [
{
"id": "43",
"titel": "Phone",
"price": "211"
},{
"id": "76",
"titel": "Battery",
"price": "34"
},{
"id": "102",
"titel": "Pen",
"price": "45"
},{
"id": "127",
"titel": "Apple",
"price": "10"
}
];
let descriptions= [
{
"description": "Good battery",
"parent": "76"
},{
"description": "Sharp pen",
"parent": "102"
},
];
let results = [];
for (const desc of descriptions) {
const product = products.find(v => v.id === desc.parent);
if (!product) {
continue;
}
results.push(Object.assign({}, product, desc));
}
console.log(results);
const result = descriptions.map(descr => {
const product = products.find(prod => prod.id === descr.parent);
return {...product, ...descr}
})
Related
I have the main three parameters that are important category, subcategory, and group
This is an array of objects and I want to change the format of this array
Like all data divide into category inside sub-category inside group wise data I want
const data =
[
{
"type": "checkbox",
"value": true,
"category": "id",
"subcategory": "id document 1",
"group": "group1"
},
{
"type": "radio",
"value": 2,
"category": "id",
"subcategory": "id document 2",
"group": "group2"
},
{
"type": "radio",
"value": 3,
"category": "id",
"subcategory": "id document 2",
"group": "group2"
},
{
"type": "string",
"value": "dfgdfg",
"category": "Services",
"subcategory": "Service A",
"group": "g1"
},
{
"type": "string",
"value": "fxs",
"category": "Services",
"subcategory": "Service A",
"group": "g1"
},
{
"type": "string",
"value": "3",
"category": "Services access",
"subcategory": "Service B",
"group": "g1"
},
{
"type": "string",
"value": "sgredfg25ghfghrt54645dfeh",
"category": "Services access",
"subcategory": "Service B",
"group": "g2"
},
{
"type": "string",
"value": "sgredfg25ghfghrt54645dfeh",
"category": "Services access",
"subcategory": "Service C",
"group": "g3"
}
]
The expected result looks like this
const data = [
{
"category": "id",
"subcategory": [
{
"subcategory_name": "id document 1",
"subcategory_data": [
{
"group": "group1",
"groupdata": [
{
"type": "checkbox",
"value": true,
"category": "id",
"subcategory": "id document 1",
"group": "group1"
}
]
}
]
},
{
"subcategory_name": "id document 2",
"subcategory_data": [
{
"group": "group1",
"groupdata": [
{
"type": "checkbox",
"value": true,
"category": "id",
"subcategory": "id document 2",
"group": "group1"
},
{
"type": "checkbox",
"value": true,
"category": "id",
"subcategory": "id document 2",
"group": "group1"
}
]
}
]
}
]
},
{
"category": "Services",
"subcategory": [
{
"subcategory_name": "Service B",
"subcategory_data": [
{
"group": "c1",
"groupdata": [
{
"type": "checkbox",
"value": true,
"category": "Services",
"subcategory": "Service B",
"group": "c1"
}
]
},
{
"group": "c2",
"groupdata": [
{
"type": "checkbox",
"value": true,
"category": "Services",
"subcategory": "Service B",
"group": "c2"
}
]
}
]
},
{
"subcategory_name": "Service C",
"subcategory_data": [
{
"group": "f1",
"groupdata": [
{
"type": "checkbox",
"value": true,
"category": "Services",
"subcategory": "Service C",
"group": "f1"
},
{
"type": "checkbox",
"value": true,
"category": "Services",
"subcategory": "Service C",
"group": "f1"
}
]
}
]
}
]
}
]
If the category match data push into the match subcategory if not then create a category for the same and if the subcategory match push into that one otherwise create a new one same as the group if the group match into subcategory then push otherwise create one
Like I want hierarchy like category => subcategory => group
And I try the this code
let finaldata = []
let flag1;
let aa = []
for (let i = 0; i < parseData.length; i++) {
if (i == 0) {
finaldata.push({ category: parseData[i].category, subcategory: [parseData[i]] })
flag1 = true
} else {
if (parseData[i - 1]?.category !== parseData[i].category) {
finaldata.push({ category: parseData[i].category, subcategory: [parseData[i]] })
} else {
aa = finaldata.map(x => x.category === parseData[i].category ? { ...x, subcategory: [...x.subcategory, parseData[i]] } : x);
}
}
if (!flag1) break;
}
does this helps?
const data =
[
{
"type": "checkbox",
"value": true,
"category": "id",
"subcategory": "id document 1",
"group": "group1"
},
{
"type": "radio",
"value": 2,
"category": "id",
"subcategory": "id document 2",
"group": "group2"
},
{
"type": "radio",
"value": 3,
"category": "id",
"subcategory": "id document 2",
"group": "group2"
},
{
"type": "string",
"value": "dfgdfg",
"category": "Services",
"subcategory": "Service A",
"group": "g1"
},
{
"type": "string",
"value": "fxs",
"category": "Services",
"subcategory": "Service A",
"group": "g1"
},
{
"type": "string",
"value": "3",
"category": "Services access",
"subcategory": "Service B",
"group": "g1"
},
{
"type": "string",
"value": "sgredfg25ghfghrt54645dfeh",
"category": "Services access",
"subcategory": "Service B",
"group": "g2"
},
{
"type": "string",
"value": "sgredfg25ghfghrt54645dfeh",
"category": "Services access",
"subcategory": "Service C",
"group": "g3"
}
]
const result = data.reduce((p, c) => {
const i = p.findIndex(p => p.category === c.category)
if (i !== -1) {
const j = p[i].subcategory.findIndex(s => s.subcategory_name === c.subcategory);
if (j !== -1) {
const k = p[i].subcategory[j].subcategory_data.findIndex(sd => sd.group === c.group);
if (k !== -1) {
p[i].subcategory[j].subcategory_data[k].groupdata.push(c);
return p;
}
p[i].subcategory[j].subcategory_data.push({
group: c.group,
groupdata: [
c
]
})
return p;
}
p[i].subcategory.push({
subcategory_name: c.subcategory,
subcategory_data: [
{
group: c.group,
groupdata: [
{
...c
}
]
}
]
})
return p
}
p.push({
category: c.category,
subcategory: [
{
subcategory_name: c.subcategory,
subcategory_data: [
{
group: c.group,
groupdata: [
c
]
}
]
}
]
})
return p;
}, []);
console.log(result);
Another approach to group items:
const data = [{"type":"checkbox","value":true,"category":"id","subcategory":"id document 1","group":"group1"},{"type":"radio","value":2,"category":"id","subcategory":"id document 2","group":"group2"},{"type":"radio","value":3,"category":"id","subcategory":"id document 2","group":"group2"},{"type":"string","value":"dfgdfg","category":"Services","subcategory":"Service A","group":"g1"},{"type":"string","value":"fxs","category":"Services","subcategory":"Service A","group":"g1"},{"type":"string","value":"3","category":"Services access","subcategory":"Service B","group":"g1"},{"type":"string","value":"sgredfg25ghfghrt54645dfeh","category":"Services access","subcategory":"Service B","group":"g2"},{"type":"string","value":"sgredfg25ghfghrt54645dfeh","category":"Services access","subcategory":"Service C","group":"g3"}];
const groupByToPairs = (items, key) => Object.entries(items.reduce((acc, item) => {
acc[item[key]] ??= [];
acc[item[key]].push(item);
return acc;
}, {}));
const makeGroups = (items) => groupByToPairs(items, 'group')
.map(([group, groupdata]) => ({ group, groupdata }));
const makeSubcategories = (items) => groupByToPairs(items, 'subcategory')
.map(([subcategory_name, items]) => ({ subcategory_name, subcategory_data: makeGroups(items) }));
const makeCategories = (items) => groupByToPairs(items, 'category')
.map(([category, items]) => ({ category, subcategory: makeSubcategories(items) }));
console.log(makeCategories(data));
.as-console-wrapper { max-height: 100% !important; top: 0 }
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>
I have an array with objects
const data = [{
"id": 19887003,
"category": "Shops",
"details": "Shoe Store",
"star": 2,
"subCategory": "Outlet",
},
{
"id": 19234003,
"category": "Shops",
"details": "Shoe Point",
"star": 2,
"subCategory": "Outlet",
},
{
"id": 190456003,
"category": "Food",
"details": "Korean",
"star": 4,
"subCategory": "Restaurant",
},
{
"id": 190111003,
"category": "Food",
"details": "Chinese",
"star": 4,
"subCategory": "Restaurant",
},
{
"id": 1902303,
"category": "Food",
"details": "Lounge",
"star": 4,
"subCategory": "Bar",
}]
this is a small piece but the structure is the same for all objects: i have a category, with multiple subcategories and sometimes the subcategory has details..for example the category food has the subcategory restourant and restourant has many types (chinese, korean).
My goal is to get a structure like that:
[
{
"category": "Food",
"subCategories": [
{
"Subcategory": "Bar",
"details": [
{
name: "Lounge",
star: 2,
id: 1902303
}
]
},
{
"Subcategory": "Restaurant",
"details": [
{
name: "Chinese",
star: 4,
id: 190111003
},
{
name: "Korean",
star: 4,
id: 190456003
}
]
}
},
{
"category": "Shops",
"subCategories": [
{
"Subcategory": "Outlet",
"details": [
{
name: "Shoe Store",
star: 2,
id: 19887003
},
{
name: "Shoe Point",
star: 2,
id: 19234003
}
]
}
]
}
]
My attempt:
const groupedCategories = data.reduce((accumulator, element) => {
const detail = element.details;
const category = element.category;
const subCategory = element.subCategory;
if (accumulator[category]){
return {
...accumulator,
[category]: {
...accumulator[category],
subCategories: [...new Set([...accumulator[category].subCategories,subCategory])],
}
}}
else {
return {
...accumulator,
[category]: {
subCategories: [subCategory],
}
}
}
}, {});
I tried use reduce method like that but this is not the exact structure I desire in particular how to put details fields into subcategories.
Thanks
array.reduce seems to be the right choice. Simplest approach is to have double if statement to check if previous element (category and subcategory exists) and either push into existing array or create new object on upper level:
const data = [{
"id": 19887003,
"category": "Shops",
"details": "Shoe Store",
"star": 2,
"subCategory": "Outlet",
},
{
"id": 19234003,
"category": "Shops",
"details": "Shoe Point",
"star": 2,
"subCategory": "Outlet",
},
{
"id": 190456003,
"category": "Food",
"details": "Korean",
"star": 4,
"subCategory": "Restaurant",
},
{
"id": 190111003,
"category": "Food",
"details": "Chinese",
"star": 4,
"subCategory": "Restaurant",
},
{
"id": 1902303,
"category": "Food",
"details": "Lounge",
"star": 4,
"subCategory": "Bar",
}]
let output = data.reduce((acc,cur) => {
let {category, subCategory, ...rest} = cur;
let prevCat = acc.find(x => x.category === category);
if(!prevCat){
acc.push({category, subCategories: [{subCategory, details: [rest]}]});
} else {
let prevSubCat = prevCat.subCategories.find(x => x.subCategory === subCategory);
if(!prevSubCat) {
prevCat.subCategories.push({subCategory, details: [rest]});
} else {
prevSubCat.details.push(rest);
}
}
return acc;
}, []);
console.log(output);
I am working on NuxtJs and i have to return a list array from a column of json data when and if matches to a value of another columns
The below code returns all unique value names from the column. But i want to get unique value names when the album name matches to "BAD" / "Thriller" alone
getNameList(){
var lookup = {};
var items = this.testdata.songs;
var result_name = [];
for (var item, i = 0; item = items[i++];) {
var unique_name = item.name;
if (!(unique_name in lookup)) {
lookup[unique_name] = 1;
result_name.push(unique_name);
}
}
return result_name
}
Please help me with some codes
json data file name "testdata.json"
{
"songs": [
{
"id": "1",
"name": "Thriller",
"album": "Thriller"
},
{
"id": "2",
"name": "Smooth Criminal",
"album": "BAD"
},
{
"id": "3",
"name": "Thriller",
"album": "Thriller"
},
{
"id": "4",
"name": "Smooth Criminal",
"album": "BAD"
},
{
"id": "5",
"name": "BAD",
"album": "BAD"
},
{
"id": "6",
"name": "Billy Jean",
"album": "Thriller"
},
{
"id": "7",
"name": "BAD",
"album": "BAD"
},
{
"id": "8",
"name": "Smooth Criminal",
"album": "BAD"
},
{
"id": "9",
"name": "BAD",
"album": "BAD"
},
{
"id": "10",
"name": "Billy Jean",
"album": "Thriller"
},
{
"id": "11",
"name": "Smooth Criminal",
"album": "BAD"
},
{
"id": "12",
"name": "Beat It",
"album": "Thriller"
},
{
"id": "13",
"name": "Billy Jean",
"album": "Thriller"
},
]
}
I am new to Javascript & nuxtjs. I tried with several if statements between the above script code, but nothing works to me.
You can filter the array by album name and use Set to get unique array value.
function getNameList(testdata){
const filteredArray = testdata.songs
.filter(item => item.album === 'BAD' || item.album === 'Thriller');
return [...new Set(filteredArray.map(item => item.name))];
}
const a = {"songs":[{"id":"1","name":"Thriller","album":"Thriller"},{"id":"2","name":"Smooth Criminal","album":"BAD"},{"id":"3","name":"Thriller","album":"Thriller"},{"id":"4","name":"Smooth Criminal","album":"BAD"},{"id":"5","name":"BAD","album":"BAD"},{"id":"6","name":"Billy Jean","album":"Thriller"},{"id":"7","name":"BAD","album":"BAD"},{"id":"8","name":"Smooth Criminal","album":"BAD"},{"id":"9","name":"BAD","album":"BAD"},{"id":"10","name":"Billy Jean","album":"Thriller"},{"id":"11","name":"Smooth Criminal","album":"BAD"},{"id":"12","name":"Beat It","album":"Thriller"},{"id":"13","name":"Billy Jean","album":"Thriller"}]};
console.log(getNameList(a));
I have a json file which contains the list of products.
[{"id":76,
"name":"A",
"description":"abc",
"price":199,
"imageUrl":"image.jpg",
"productCategory":[{
"categoryId":5,
"category":null
},{
"categoryId":6,
"category":null
}
]}
I then have a second json file with a list of categories which look like so:
[{"id":5,"name":"red"},
{"id":6,"name”:"blue"}]
What is the best way to join the categories of this two json files in Angular?
This is what I aim to achieve:
[{"id":76,
"name":"A",
"description":"abc",
"price":199,
"imageUrl":"image.jpg",
"productCategory":[{
"categoryId":5,
"category":red
},{
"categoryId":6,
"category":blue
}
]}
You can use filter function for your requirement as below
let products = [{
"id": 76,
"name": "A",
"description": "abc",
"price": 199,
"imageUrl": "image.jpg",
"productCategory": [{
"categoryId": 2,
"category": null
}, {
"categoryId": 1,
"category": null
}]
}, {
"id": 77,
"name": "B",
"description": "abcd",
"price": 1997,
"imageUrl": "image.jpg",
"productCategory": [{
"categoryId": 5,
"category": null
}, {
"categoryId": 6,
"category": null
}]
},
{
"id": 78,
"name": "C",
"description": "abcde",
"price": 1993,
"imageUrl": "image.jpg",
"productCategory": [{
"categoryId": 4,
"category": null
}, {
"categoryId": 6,
"category": null
}]
}];
let category = [{ "id": 5, "name": "red" }, { "id": 6, "name": "blue" }]
let result = products.filter(p => {
var exist = p.productCategory.filter(pc => category.find(c => c.id == pc.categoryId))[0];
return exist;
});
console.log(result);
let products = [{
"id": 76,
"name": "A",
"description": "abc",
"price": 199,
"imageUrl": "image.jpg",
"productCategory": [{
"categoryId": 2,
"category": null
}, {
"categoryId": 1,
"category": null
}]
}, {
"id": 77,
"name": "B",
"description": "abcd",
"price": 1997,
"imageUrl": "image.jpg",
"productCategory": [{
"categoryId": 5,
"category": null
}, {
"categoryId": 6,
"category": null
}]
},
{
"id": 78,
"name": "C",
"description": "abcde",
"price": 1993,
"imageUrl": "image.jpg",
"productCategory": [{
"categoryId": 4,
"category": null
}, {
"categoryId": 6,
"category": null
}]
}];
let category = [{ "id": 5, "name": "red" }, { "id": 6, "name": "blue" }]
let result = products.filter(p => {
var exist = p.productCategory.filter(pc => category.find(c => c.id == pc.categoryId))[0];
return exist;
});
console.log(result);
I make a stackblitz that use a service to retreive the data. Yes, the way is using switchMap and map. SwitchMap receive an array and must return an observable. with map, we transform the data received and return the data transformed
this.dataService.getCategories().pipe(
//first get the categories, the categories is in the
//variable cats
switchMap((cats:any[])=>{
return this.dataService.getProducts().pipe(map((res:any[])=>{
res.forEach(p=>{ //with each product
p.productCategory.forEach(c=>{ //with each productCategory in product
//equals a propertie "category" to the propertie "name" of the cats
c.category=cats.find(x=>x.id==c.categoryId).name
})
})
return res
}))
})).subscribe(res=>{
console.log(res)
})
If only has an unique product we can make
this.dataService.getCategories().pipe(
switchMap((cats:any[])=>{
return this.dataService.getUniqProduct(2).pipe(map((res:any)=>{
res.productCategory.forEach(c=>{
c.category=cats.find(x=>x.id==c.categoryId).name
})
return res
}))
})).subscribe(res=>{
console.log(res)
})
We can improve our dataService "cached" the categories
getCategories() {
if (this.categories)
return of(this.categories);
return http.get(......).pipe(tap(res=>{
this.categories=res;
}))
}
NOTE:In the stackbit I simulate the call to an http.get(...) using "of"
I have 2 arrays objects and I need to do a count of home many types of card we have.
The first object contains all the car id's and the second list contains the types of cars.
Here is the data:
var arr = {
"categories": [{
"id": "100",
"name": "category name",
"car_id": "1"
}, {
"id": "192",
"name": "category name here",
"car_id": "25"
}, {
"id": "192",
"name": "category name here",
"car_id": "27"
}]
};
var arr2 = {
"cars": [{
"id": "1",
"name": "car name",
"car_id": "1",
"type": "ford"
}, {
"id": "4",
"name": "name 2",
"car_id": "25",
"type": "ford"
}, {
"id": "4",
"name": "name 2",
"car_id": "27",
"type": "fiat"
}]
};
There's only 5 types of cars so I have 5 variables:
var:
ford,
fiat,
mazda,
mini,
mg
So, what I need to end up with is something like this:
ford: 2;
fiat: 1;
mazda: 0;
mini: 0;
mg: 0;
How can I do this?
If your number of types are fixed, then try this approach
Make an map first
var map = {
ford: 0,
fiat: 0,
mazda: 0,
mini: 0,
mg: 0
};
Now iterate the arrays and count by types
arr2.cars.forEach( function( item ){
map[ item.type ]++;
});
your map is populated with the values now.
var arr2 = {
"cars": [{
"id": "1",
"name": "car name",
"car_id": "1",
"type": "ford"
}, {
"id": "4",
"name": "name 2",
"car_id": "25",
"type": "ford"
}, {
"id": "4",
"name": "name 2",
"car_id": "27",
"type": "fiat"
}]
};
var map = {
ford: 0,
fiat: 0,
mazda: 0,
mini: 0,
mg: 0
};
arr2.cars.forEach(function(item) {
map[item.type] ++;
});
console.log(map);
var arr = {
"categories": [{
"id": "100",
"name": "category name",
"car_id": "1"
}, {
"id": "192",
"name": "category name here",
"car_id": "25"
}, {
"id": "192",
"name": "category name here",
"car_id": "27"
}]
};
var arr2 = {
"cars": [{
"id": "1",
"name": "car name",
"car_id": "1",
"type": "ford"
}, {
"id": "4",
"name": "name 2",
"car_id": "25",
"type": "ford"
}, {
"id": "4",
"name": "name 2",
"car_id": "27",
"type": "fiat"
}]
};
var carCount, typeCount;
arr.categories.forEach(function(item){
if(item.hasOwnProperty("car_id")){
carCount = arr.categories.length;
}
});
arr2.cars.forEach(function(item){
if(item.hasOwnProperty("type")){
typeCount = arr2.cars.length;
}
});
console.log(carCount);
console.log(typeCount);
https://jsfiddle.net/Law7rzc2/
All you need is
countBy(arr2.cars, 'type')
The implementation of countBy is left as an exercise.
Array.prototype.reduce is your go-to for this kind of array computation. A Map will help you keep track of unique car makes as you iterate thru the array of cars.
var obj2 = {
"cars": [{
"id": "1",
"name": "car name",
"car_id": "1",
"type": "ford"
}, {
"id": "4",
"name": "name 2",
"car_id": "25",
"type": "ford"
}, {
"id": "4",
"name": "name 2",
"car_id": "27",
"type": "fiat"
}]
};
const typeStat = cars => {
let map = cars.reduce((m, {type}) =>
m.set(type, (m.get(type) || 0) + 1), new Map());
return Array.from(map, ([make, count]) => ({make, count}));
};
let stats = typeStat(obj2.cars)
console.log(stats);
Output
[
{
"make": "ford",
"count": 2
},
{
"make": "fiat",
"count": 1
}
]