Convert array in objects to individual strings - javascript

How can I split an array of images among an object?
For example, using the JSON below. How can produce a return string of each itemUrl and it's associated productCode?
This JSON
{
"products": [
{
"productCode": "ID1",
"images": [
{
"id": 1,
"itemUrl": "https://img.com/1.JPG"
},
{
"id": 2,
"itemUrl": "https://img.com/2.JPG"
}
]
},
{
"productCode": "ID2",
"images": [
{
"id": 3,
"itemUrl": "https://img.com/3.JPG"
},
{
"id": 4,
"itemUrl": "https://img.com/4.JPG"
},
{
"id": 5,
"itemUrl": "https://img.com/5.JPG"
}
]
}
]
}
Becomes
https://img.com/1.JPG
https://img.com/2.JPG
https://img.com/3.JPG
https://img.com/4.JPG
https://img.com/5.JPG
Currently, if I were to use
for (const tour of data.products) {
console.log(tour.images[0].itemUrl);
...
the return would obviously return
https://img.com/1.JPG
https://img.com/3.JPG
however, when
let imageEach = tour.images;
let output = [];
imageEach.forEach(item => {
output.push(item.itemUrl);
});
...
I get a return of
[{
https://img.com/1.JPG,
https://img.com/2.JPG
}]
[{
https://img.com/3.JPG
https://img.com/4.JPG
https://img.com/5.JPG
}]

You can try something like this using Array.reduce to iterate over the products and Array.map to go through the items and get the itemUrl:
const data = { "products": [ { "productCode": "ID1", "images": [ { "id": 1, "itemUrl": "https://img.com/1.JPG" }, { "id": 2, "itemUrl": "https://img.com/2.JPG" } ] }, { "productCode": "ID2", "images": [ { "id": 3, "itemUrl": "https://img.com/3.JPG" }, { "id": 4, "itemUrl": "https://img.com/4.JPG" }, { "id": 5, "itemUrl": "https://img.com/5.JPG" } ] } ] }
const result = data.products.reduce((r,{images}) => {
r.push(...images.map(x => x.itemUrl))
return r
}, [])
console.log(result.join('\n'))
Or even shorter as suggested by #Prassana by using ES6 array spread some more:
const data = { "products": [ { "productCode": "ID1", "images": [ { "id": 1, "itemUrl": "https://img.com/1.JPG" }, { "id": 2, "itemUrl": "https://img.com/2.JPG" } ] }, { "productCode": "ID2", "images": [ { "id": 3, "itemUrl": "https://img.com/3.JPG" }, { "id": 4, "itemUrl": "https://img.com/4.JPG" }, { "id": 5, "itemUrl": "https://img.com/5.JPG" } ] } ] }
const result = data.products.reduce((r,{images}) =>
[...r, ...images.map(x => x.itemUrl)], [])
console.log(result.join('\n'))

Try
var result = [];
for (var i = 0; i < data.products.length; i++) {
for (var j = 0; j < data.products[i].images.length; j++){
result.push(data.products[i].images[j].itemUrl);
}
}
console.log(result);

You need Array.concat
const data = {
"products": [
{
"productCode": "ID1",
"images": [
{
"id": 1,
"itemUrl": "https://img.com/1.JPG"
},
{
"id": 2,
"itemUrl": "https://img.com/2.JPG"
}
]
},
{
"productCode": "ID2",
"images": [
{
"id": 3,
"itemUrl": "https://img.com/3.JPG"
},
{
"id": 4,
"itemUrl": "https://img.com/4.JPG"
},
{
"id": 5,
"itemUrl": "https://img.com/5.JPG"
}
]
}
]
}
let urls = []
data.products.forEach(item => {
urls = urls.concat(item.images.map(img => img.itemUrl))
})
console.log(urls)

You could try this.
let json = {
"products": [
{
"productCode": "ID1",
"images": [
{
"id": 1,
"itemUrl": "https://img.com/1.JPG"
},
{
"id": 2,
"itemUrl": "https://img.com/2.JPG"
}
]
},
{
"productCode": "ID2",
"images": [
{
"id": 3,
"itemUrl": "https://img.com/3.JPG"
},
{
"id": 4,
"itemUrl": "https://img.com/4.JPG"
},
{
"id": 5,
"itemUrl": "https://img.com/5.JPG"
}
]
}
]
}
json.products.forEach(product => {
console.log(product.productCode + ": ")
product.images.forEach(i => console.log(i.itemUrl))
});
// or
json.products.forEach(product => {
product.images.forEach(i => console.log(product.productCode + " : " + i.itemUrl))
});

products.reduce((urls, product, i) => {
const imageURLs = product.images.map(img => img.itemUrl);
urls = urls.concat(imageURLs);
return urls;
}, []);
Try this

You can try my code to produce following result
{
"ID1" : ["https://img.com/1.JPG","https://img.com/2.JPG"],
"ID2" : ["https://img.com/3.JPG","https://img.com/4.JPG","https://img.com/5.JPG"]
}
Below is the code. Lets take your mentioned JSON data as "obj"(a variable)
obj.products.reduce((acc, product)=>{
acc[product.productcode] = product.images.map(img => img.itemUrl)
return acc
}, {})

Related

Javascript: How to loop through array of objects for post request for array property?

I have an array response and i need to pass post request data from that response. The response have nested array objects as well. So how to loop through those array objects into post api request key values ?
Response which i am getting is as below:
records = "data": [
{
"id": 1,
"title": "Black Panther",
"product_images": [
{
"id": 1,
"images": {
"id": 1,
"thumbnail_image": "/assets/1/image.jpg",
},
},
{
"id": 2,
"images": {
"id": 2,
"thumbnail_image": "/assets/2/image.jpg",
},
}
],
product_categories: [
{
"id": 1,
"categories": {
"id": 3,
"category_name": "Outdoor Sports"
}
}
]
}
]
Now i need to pass that product_images array object's images.thumbnail_image property into the post request key value.
records.map((element) => {
let data;
data = {
"id": element.id,
"name": element.title,
"image_files":
[
{
"url": "" // need to pass thumbnail_image value over here.
}
],
"product_category": {
"category_id": [1,2] // need to pass product_categories[i].categories.id value over here.
}
}
})
axios post API request is as below:
axios({
method: 'post',
url: 'api_url',
data: {
"products": data,
}
}).then((response) => {
console.log(response);
}).catch((error) => {
console.log(error)
});
P.S: I have tried to manage this issue with loop through into the image_files array as below but that is working.
"image_files": [
element.product_images.map((ele) => {
{
"url": ele.images.thumbnail_image
}
})
]
::Updated::
I also need to manage that category property into the post api request. I have tried like this way but it pass the [null] value
"category_id": lists.campaign_product_categories.map((element) => {
let arr = []
arr.push(element.categories.id)
}),
You can use a nested map statement with destructuring to achieve this.
let records = [ { "id": 1, "title": "Black Panther", "product_images": [ { "id": 1, "images": { "id": 1, "thumbnail_image": "/assets/1/image.jpg", }, }, { "id": 2, "images": { "id": 2, "thumbnail_image": "/assets/2/image.jpg", }, } ] } ];
let data = records.map(({id, title:name, product_images}) => (
{
id, name,
"image_files": product_images.map(({images:{thumbnail_image: url}})=>({
url
}))
}
));
console.log(data);
You can just map the sub array for each array element like so:
const records = [
{
id: 1,
title: "Black Panther",
product_images: [
{
id: 1,
images: {
id: 1,
thumbnail_image: "/assets/1/image.jpg",
},
},
{
id: 2,
images: {
id: 2,
thumbnail_image: "/assets/2/image.jpg",
},
},
],
},
];
const mapped = records.map((element) => ({
id: element.id,
name: element.title,
image_files: element.product_images.map((i) => ({
url: i.images.thumbnail_image,
})),
}));
console.log(mapped);
You need to run a map on the product images inner array to create the URL array
let apiResponses = records.data.map((dataElement) => {
let urls = dataElement.product_images.map((product_image) => {
return {"url": product_image.images.thumbnail_image}
})
return {
"id": dataElement.id,
"name": dataElement.title,
"image_files":
urls,
}
})
console.log(apiResponses[0])
Outputs
{
id: 1,
name: 'Black Panther',
image_files: [ { url: '/assets/1/image.jpg' }, { url: '/assets/2/image.jpg' } ]
}
Full code below
let records = {"data": [
{
"id": 1,
"title": "Black Panther",
"product_images": [
{
"id": 1,
"images": {
"id": 1,
"thumbnail_image": "/assets/1/image.jpg",
},
},
{
"id": 2,
"images": {
"id": 2,
"thumbnail_image": "/assets/2/image.jpg",
},
}
]
}
]}
let apiResponses = records.data.map((dataElement) => {
let urls = dataElement.product_images.map((product_image) => {
return {"url": product_image.images.thumbnail_image}
})
return {
"id": dataElement.id,
"name": dataElement.title,
"image_files":
urls,
}
})
console.log(apiResponses[0])
You forgot the return statement
records.map((element) => {
let data;
data = {
"id": element.id,
"name": element.title,
"image_files":
[
{
"url": "" // need to pass thumbnail_image value over here.
}
],
}
return data; // <------- this line
})

How to find a value in multilevel Array of objects

I'm trying to implement a search box in which if i start searching for a value it will look for the target in an nested array of objects which is like this:--
[
{
"groupId": 1,
"groupName": "Americas",
"groupItems": [
{
"id": 5,
"name": "Brazil",
"parentID": 1,
"parentName": "Americas"
},
{
"id": 6,
"name": "Canada",
"parentID": 1,
"parentName": "Americas"
}
],
"isExpanded": false,
"toggleAllSelection": false
},
{
"groupId": 2,
"groupName": "APAC",
"groupItems": [
{
"id": 7,
"name": "Australia",
"parentID": 2,
"parentName": "APAC"
},
{
"id": 8,
"name": "China",
"parentID": 2,
"parentName": "APAC"
}
],
"isExpanded": false,
"toggleAllSelection": false
},
{
"groupId": 3,
"groupName": "Europe",
"groupItems": [
{
"id": 9,
"name": "Belgium",
"parentID": 3,
"parentName": "Europe"
},
{
"id": 7,
"name": "Austria",
"parentID": 2,
"parentName": "APAC"
},
{
"id": 10,
"name": "Bulgaria",
"parentID": 3,
"parentName": "Europe"
}
],
"isExpanded": false,
"toggleAllSelection": false
}
]
Now i want to search for name property in each groupItems array of objects in group array. and when there is a match my function should return data in same format and as it will be autocomplete so instead of exact match it should be partial match. So if search aus in input box it should return
[{
"groupId": 2,
"groupName": "APAC",
"groupItems": [
{
"id": 7,
"name": "Australia",
"parentID": 2,
"parentName": "APAC"
}],
"isExpanded": false,
"toggleAllSelection": false,
},
{
"groupId": 3,
"groupName": "Europe",
"groupItems": [
{
"id": 7,
"name": "Austria",
"parentID": 2,
"parentName": "APAC"
}
],
"isExpanded": false,
"toggleAllSelection": false
}
]
const findByName = (data, name) => {
const result = data.reduce((m, { groupItems, ...rest }) => {
let mapGrpItems = (groupItems || []).filter((item) =>
item.name.includes(name)
);
if (mapGrpItems.length) {
m.push({ ...rest, groupItems: mapGrpItems });
}
return m;
}, []);
return result;
};
const findByName = (data, name) => {
const result = data.reduce((m, { groupItems, ...rest }) => {
let mapGrpItems = (groupItems || []).filter((item) =>
item.name.includes(name)
);
if (mapGrpItems.length) {
m.push({ ...rest, groupItems: mapGrpItems });
}
return m;
}, []);
return result;
};
const data = [{"groupId":1,"groupName":"Americas","groupItems":[{"id":5,"name":"Brazil","parentID":1,"parentName":"Americas"},{"id":6,"name":"Canada","parentID":1,"parentName":"Americas"}],"isExpanded":false,"toggleAllSelection":false},{"groupId":2,"groupName":"APAC","groupItems":[{"id":7,"name":"Australia","parentID":2,"parentName":"APAC"},{"id":8,"name":"China","parentID":2,"parentName":"APAC"}],"isExpanded":false,"toggleAllSelection":false},{"groupId":3,"groupName":"Europe","groupItems":[{"id":9,"name":"Belgium","parentID":3,"parentName":"Europe"},{"id":7,"name":"Austria","parentID":2,"parentName":"APAC"},{"id":10,"name":"Bulgaria","parentID":3,"parentName":"Europe"}],"isExpanded":false,"toggleAllSelection":false}]
console.log(JSON.stringify(findByName(data, "Aus"), null, 2));
I would definitely attempt to reason through what you're trying to do before just implementing this. Being able to reason through solutions like this is 99% of the job when it comes to programming.
function filterGroups(filter) {
const result = [];
myObj.forEach(group => {
const filteredGroups = group.groupItems.filter(groupItem => {
return groupItem.name.toLowerCase().includes(filter);
});
if (filteredGroups.length > 1) {
result.push({
...group,
groupItems: filteredGroups
});
}
});
return result;
}
You can use Arrays.filter for the group items in each outer object in your JSON array to filter out the items which match your search query. You can write something like this:
let autocomplete = (key) => {
// arr = Your Data
let result = []
arr.forEach(grp=> {
let out = grp
let res = grp.groupItems.filter(item => item.name.toLowerCase().includes(key.toLowerCase()))
if(res.length!=0)
{
out.groupItems = res
result.push(out)}
})
return result

Sort Array of Objects Childs to new Array with Objects

I'm programming a small vue.js App and need to convert an array to a new one and sort them.
The array of objects I get from the backend server looks like that:
var arr =
[
{
"id": 1,
"name": "Name1",
"parents": {
"someOtherTings": "Test",
"partentOfParent": {
"mainId": 10
}
}
},
{
"id": 2,
"name": "Name2",
"parents": {
"someOtherTings": "Test",
"partentOfParent": {
"mainId": 11
}
}
},
{
"id": 3,
"name": "Name3",
"parents": {
"someOtherTings": "Test",
"partentOfParent": {
"mainId": 10
}
}
}
]
console.log(arr)
But I need a new array, that is sorted like that:
var newArr =
[
{
"mainId": 10,
"parents": {
"id": 1,
"name": "Name1"
}
},
{
"mainId": 11,
"parents": [
{
"id": 2,
"name": "Name2"
},
{
"id": 3,
"name": "Name3"
}
]
}
]
What is the best way to implement this?
You could group the items with the help of a Map.
var array = [{ id: 1, name: "Name1", parents: { someOtherTings: "Test", partentOfParent: { mainId: 10 } } }, { id: 2, name: "Name2", parents: { someOtherTings: "Test", partentOfParent: { mainId: 11 } } }, { id: 3, name: "Name3", parents: { someOtherTings: "Test", partentOfParent: { mainId: 10 } } }],
result = Array.from(
array.reduce(
(m, { id, name, parents: { partentOfParent: { mainId } } }) =>
m.set(mainId, [...(m.get(mainId) || []), { id, name }]),
new Map
),
([mainId, parents]) => ({ mainId, parents })
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You just need a combination of map to create a new array and then sort it based on the mainId value
var arr = [{
"id": 1,
"name": "Name1",
"parents": {
"someOtherTings": "Test",
"partentOfParent": {
"mainId": 10
}
}
},
{
"id": 2,
"name": "Name2",
"parents": {
"someOtherTings": "Test",
"partentOfParent": {
"mainId": 11
}
}
},
{
"id": 3,
"name": "Name3",
"parents": {
"someOtherTings": "Test",
"partentOfParent": {
"mainId": 10
}
}
}
]
const newArr = arr.map(obj => ({
mainId: obj.parents.partentOfParent.mainId,
parents: {
id: obj.id,
name: obj.name
},
})).sort((a, b) => b - a);
console.log(newArr);

Javascript(NodeJs) - Conversion of Arrays and Objects to bulk insert in mysql(Sequelize)

This is my json:
{
"senderName": "ifelse",
"message": "Hi",
"groups": [
{
"id": 14,
"groupname": "Angular",
"contactgroups": [
{
"id": 1,
"contact": {
"id": 1,
"gsm": "123456789"
}
},
{
"id": 3,
"contact": {
"id": 2,
"gsm": "111111111"
}
}],
"select": true
}],
"draftData": {
"contacts": [
]
}
}
How to make the above json into:
[{phoneno: 123456789; sender: ifelse ; message: Hi},{phoneno: 11111111; sender: ifelse ; message: Hi}]
I want to take phoneno data from gsm object key
Which is best method to do this? for or forEach or anyother?
I guess, this is what you want. Use map to convert contactgroups to new array with phoneno.
var data = {
"senderName": "ifelse",
"message": "Hi",
"groups": [{
"id": 14,
"groupname": "Angular",
"contactgroups": [{
"id": 1,
"contact": {
"id": 1,
"gsm": "123456789"
}
},
{
"id": 3,
"contact": {
"id": 2,
"gsm": "111111111"
}
}
],
"select": true
}],
"draftData": {
"contacts": []
}
}
var result = data.groups[0].contactgroups.map(i => {
return {
phoneno: i.contact.gsm,
sender: data.senderName,
message: data.message
}
})
console.log(result);

create new json from existing json using AngularJS or Javascript

Category JSON
I am getting this JSON by accessing API and soring it in $scope.categoryList
[
{
"id": 1,
"name": "Men"
},
{
"id": 2,
"name": "Women"
},
{
"id": 3,
"name": "Kids"
}
]
SubCategory JSON
I am getting this JSON by accessing API and soring it in $scope.subCategoryList
[
{
"id": 1,
"category_id": 1,
"name": "Footwear"
},
{
"id": 2,
"category_id": 2,
"name": "Footwear"
},
{
"id": 3,
"category_id": 1,
"name": "Cloths"
}
]
I need to design this in below format
[
{
"categoryId" : 1,
"categoryName" : "Men",
"subCategory" : [
{
"subCategoryId": 1,
"subCategoryName": "Footwear"
},
{
"subCategoryId": 3,
"subCategoryName": "Cloths"
},
]
},
{
"categoryId" : 2,
"categoryName" : "Women",
"subCategory" : [
{
"subCategoryId": 2,
"subCategoryName": "Footwear"
}
]
},
{
"categoryId" : 3,
"categoryName" : "Kids",
"subCategory" : []
}
]
I have the code but it is not showing perfect data
$scope.catSubCat = []
angular.forEach($scope.subcategoryList, function(subValue, subKey) {
$scope.subCat = {
'subCategoryId' : '',
'subCategoryName' : ''
}
angular.forEach($scope.categoryList, function(catValue, catKey) {
if(subValue.category_id == catValue.id) {
$scope.subCat.subCategoryId = subValue.id;
$scope.subCat.subCategoryName = subValue.name;
$scope.subCategory = {
'categoryId' : '',
'categoryName' : '',
'subCatName' : []
}
$scope.catVal.categoryId = subValue.category_id;
$scope.catVal.categoryName = catValue.name;
$scope.catVal.subCatName.push($scope.subCat);
}
$scope.catSubCat.push($scope.catVal);
});
});
This should do the trick. Not as clean as 31piy's (wow!) but more efficient. (O(N + M) as opposed to O(N * M))
const categoryList = [
{
"id": 1,
"name": "Men"
},
{
"id": 2,
"name": "Women"
},
{
"id": 3,
"name": "Kids"
}
];
const subCategoryList = [
{
"id": 1,
"category_id": 1,
"name": "Footwear"
},
{
"id": 2,
"category_id": 2,
"name": "Footwear"
},
{
"id": 3,
"category_id": 1,
"name": "Cloths"
}
];
const mergeCategoryLists = (categoryList, subCategoryList) => {
// Turn categoryList into an object with categoryId as key
const categoryById = {};
categoryList.forEach((category) => {
categoryById[category.id] = {
categoryName: category.name,
categoryId: category.id,
subCategory: []
};
});
// Add subcategories
subCategoryList.forEach((subCategory) => {
const formattedSubCategory = {
subCategoryId: subCategory.id,
subCategoryName: subCategory.name
};
categoryById[subCategory.category_id].subCategory.push(formattedSubCategory);
});
// Convert categoryById into desired format
return Object.values(categoryById);
};
console.log(mergeCategoryLists(categoryList, subCategoryList));
Check out this logic .
$scope.newArray = angular.copy($scope.categoryList);
$scope.catSubCat = []
angular.forEach($scope.subcategoryList, function(subValue, subKey) {
$scope.subCat = {
'subCategoryId' : '',
'subCategoryName' : ''
}
angular.forEach($scope.newArray, function(catValue, catKey) {
$scope.subCat.subCategoryId = subValue.id;
$scope.subCat.subCategoryName = subValue.name;
if(subValue.category_id == catValue.id) {
if(catValue.subCatName.hasOwnProperty('bye')){
$scope.newArray[catKey].subCatName = [];
$scope.newArray[catKey].subCatName.push($scope.subCat);
}else{
$scope.newArray[catKey].subCatName.push($scope.subCat);
}
}
});
});
Resultant will we in $scope.newArray
You can use Array#map in combination with Array#filter to achieve the desired results:
var categories = [{
"id": 1,
"name": "Men"
},
{
"id": 2,
"name": "Women"
},
{
"id": 3,
"name": "Kids"
}
];
var subcategories = [{
"id": 1,
"category_id": 1,
"name": "Footwear"
},
{
"id": 2,
"category_id": 2,
"name": "Footwear"
},
{
"id": 3,
"category_id": 1,
"name": "Cloths"
}
];
var result = categories.map(cat => {
return {
categoryId: cat.id,
categoryName: cat.name,
subCategory: subcategories
.filter(subc => subc.category_id === cat.id)
.map(subc => {
return {
subCategoryId: subc.id,
subCategoryName: subc.name
};
})
};
});
console.log(result);
var categoryList = [{
"id": 1,
"name": "Men"
}, {
"id": 2,
"name": "Women"
}, {
"id": 3,
"name": "Kids"
}];
var subCategoryList = [{
"id": 1,
"category_id": 1,
"name": "Footwear"
}, {
"id": 2,
"category_id": 2,
"name": "Footwear"
}, {
"id": 3,
"category_id": 1,
"name": "Cloths"
}];
var finalJson = [];
for (var i = 0; i < categoryList.length; i++) {
var obj = {
categoryId: categoryList[i].id,
categoryName: categoryList[i].name,
subCategory: []
};
var subCat = subCategoryList.filter(function(word) {
return word.category_id === categoryList[i].id;
});
for (var j = 0; j < subCat.length; j++) {
var obj2 = {
subCategoryId: subCat[j].id,
subCategoryName: subCat[j].name
};
obj.subCategory.push(obj2);
}
finalJson.push(obj);
}
console.log(finalJson);
Pure Javascript solution to your question, you can replace with
Angular Syntax then..
Use following code:
$scope.catSubCat = []
angular.forEach($scope.categoryList, function(catValue, catKey) {
var catObj = {
'categoryId' : '',
'categoryName' : '',
'subCatName' : []
}
catObj.categoryId = catValue.id;
catObj.categoryId = catValue.name;
angular.forEach($scope.subcategoryList, function(subValue, subKey) {
if(subValue.category_id == catValue.id) {
var subCatObj = {
'subCategoryId' : '',
'subCategoryName' : ''
}
subCatObj.subCategoryId = subValue.category_id;
subCatObj.subCategoryName = catValue.name;
catObj.subCatName.push(subCatObj);
}
});
$scope.catSubCat.push(catObj);
});

Categories