Related
This question already has an answer here:
How to merge two list of objects in a new one by date
(1 answer)
Closed 8 months ago.
I'm learning Javascript and I'm stuck in a doubt with the joining of two arrays of objects through an ID, I can join the two, but the result is not what I expect.
So, I have these two object arrays:
"product": [
{
"id": "1000",
"code": "f230fh0g3",
"name": "Bamboo Watch",
"description": "Product Description",
"image": "bamboo-watch.jpg",
"price": 65,
"category": "Accessories",
"quantity": 24,
}
]
"orders": [
{
"id": "1000",
"productID": "f230fh0g3",
"date": "2020-09-13",
"amount": 65,
"quantity": 1,
},
{
"id": "1000",
"productID": "f230fh0g3",
"date": "2020-09-13",
"amount": 65,
"quantity": 1,
},
]
and I want to join both by key (id) to get one array like this one:
"product": [
{
"id": "1000",
"code": "f230fh0g3",
"name": "Bamboo Watch",
"description": "Product Description",
"image": "bamboo-watch.jpg",
"price": 65,
"category": "Accessories",
"quantity": 24,
"orders": [
{
"id": "1000",
"productCode": "f230fh0g3",
"date": "2020-09-13",
"amount": 65,
"quantity": 1,
"customer": "David James",
"status": "PENDING"
},
{
"id": "1001",
"productCode": "f230fh0g3",
"date": "2020-05-14",
"amount": 130,
"quantity": 2,
"customer": "Leon Rodrigues",
"status": "DELIVERED"
},
]
},
{
"id": "1001",
"..."
"orders": [
{
"id": "1001",
"..."
}
]
}]
Is it possible to map these arrays in this way?
Thanks in advance
Yes, it is possible. You can use .map() and .filter() together. Assuming you have products in product variable and orders in order variable, you can compute your combined list like this:
const result = products.map(
product => ({
...product,
orders: orders.filter(
({ productID }) => productID === product.id
)
})
);
I have below JSON for example where I need to extract all categories Id from the last subcategory if its not empty. For instance: On below JSON I need Ids like mens-apparel-ricky inside last categories object but if this categories was empty I like to extract the last ID like womens-new-arrivals. Basically it should be the list of all these ID's extracted.
Thanks in Advance
"categories": [{
"id": "featured",
"name": "NEW ARRIVALS",
"categories": [{
"id": "featured-new-arrivals",
"name": "New Arrivals",
"categories": [{
"id": "mens-new-arrivals",
"name": "Mens",
"categories": []
}, {
"id": "womens-new-arrivals",
"name": "Womens",
"categories": [{
"id": "mens-apparel-ricky",
"name": "Relaxed",
"categories": []
}, {
"id": "new-arrivals-kids",
"name": "Kids",
"categories": []
}, {
"id": "new-arrivals-accessories",
"name": "Accessories",
"categories": []
}]
}, {
"id": "collections",
"name": "Featured",
"categories": [{
"id": "spring-shop",
"name": "Spring Shop",
"categories": [{
"id": "spring-shop-mens",
"name": "Spring Shop Men's",
"categories": []
}, {
"id": "spring-shop-womens",
"name": "Spring Shop Women's",
"categories": []
}]
}, {
"id": "the-festival-shop",
"name": "The Festival Shop",
"categories": [{
"id": "mens-festival-shop",
"name": "Mens Festival Shop",
"categories": []
}, {
"id": "womens-festival-shop",
"name": "Womens Festival Shop",
"categories": []
}]
}, {
"id": "buddha-collections",
"name": "The Icons Shop",
"categories": [{
"id": "buddha-collections-men",
"name": "Mens",
"categories": []
}, {
"id": "buddha-collections-women",
"name": "Womens",
"categories": []
}]
}, {
"id": "all-black",
"name": "All Black Everything",
"categories": []
}]
}]
}, {
"id": "denim",
"name": "DENIM",
"categories": [{
"id": "denim-view-all",
"name": "Shop All Denim",
"categories": [{
"id": "denim-view-all-mens",
"name": "Mens Denim",
"categories": []
}, {
"id": "denim-view-all-womens",
"name": "Womens Denim",
"categories": []
}, {
"id": "denim-view-all-kids",
"name": "Kids Denim",
"categories": []
}]
}, {
"id": "denim-collections",
"name": "Featured",
"categories": [{
"id": "denim-collections-signature-stitch",
"name": "Big T & Super T Stitch",
"categories": []
}, {
"id": "denim-collections-lighten-up",
"name": "Light Wash Denim",
"categories": []
}, {
"id": "dark-wash-denim",
"name": "Dark Wash Denim",
"categories": []
}]
}]
}]
}
This is what I have tried but being new to coding getting difficult to get list form this complex structure.
var rootCategories = (jsonData.categories);
for (var i=0; i < rootCategories.length; i++)
{
var firstChild = (jsonData.categories[i].categories);
for (var j=0; j < firstChild.length; j++)
{
if ((firstChild[j].categories[j].length != 0)) {
catId = firstChild[j].categories[j].id
console.log(catId);
}
}
}
Below is one possible way to achieve the target.
Code Snippet
// recursive method to get "id"s
const getIds = arr => (
arr.flatMap( // iterate using ".flatMap()" to avoid nesting
({id, categories}) => { // de-structure to directly access "id" & "categories"
if ( // if "categories" is not empty, recurse to next level
Array.isArray(categories) &&
categories.length > 0
) {
return getIds(categories);
} else { // if it is empty, simply return the id
return id;
}
}
)
);
const rawData = {
"categories": [{
"id": "featured",
"name": "NEW ARRIVALS",
"categories": [{
"id": "featured-new-arrivals",
"name": "New Arrivals",
"categories": [{
"id": "mens-new-arrivals",
"name": "Mens",
"categories": []
}, {
"id": "womens-new-arrivals",
"name": "Womens",
"categories": [{
"id": "mens-apparel-ricky",
"name": "Relaxed",
"categories": []
}, {
"id": "new-arrivals-kids",
"name": "Kids",
"categories": []
}, {
"id": "new-arrivals-accessories",
"name": "Accessories",
"categories": []
}]
}, {
"id": "collections",
"name": "Featured",
"categories": [{
"id": "spring-shop",
"name": "Spring Shop",
"categories": [{
"id": "spring-shop-mens",
"name": "Spring Shop Men's",
"categories": []
}, {
"id": "spring-shop-womens",
"name": "Spring Shop Women's",
"categories": []
}]
}, {
"id": "the-festival-shop",
"name": "The Festival Shop",
"categories": [{
"id": "mens-festival-shop",
"name": "Mens Festival Shop",
"categories": []
}, {
"id": "womens-festival-shop",
"name": "Womens Festival Shop",
"categories": []
}]
}, {
"id": "buddha-collections",
"name": "The Icons Shop",
"categories": [{
"id": "buddha-collections-men",
"name": "Mens",
"categories": []
}, {
"id": "buddha-collections-women",
"name": "Womens",
"categories": []
}]
}, {
"id": "all-black",
"name": "All Black Everything",
"categories": []
}]
}]
}, {
"id": "denim",
"name": "DENIM",
"categories": [{
"id": "denim-view-all",
"name": "Shop All Denim",
"categories": [{
"id": "denim-view-all-mens",
"name": "Mens Denim",
"categories": []
}, {
"id": "denim-view-all-womens",
"name": "Womens Denim",
"categories": []
}, {
"id": "denim-view-all-kids",
"name": "Kids Denim",
"categories": []
}]
}, {
"id": "denim-collections",
"name": "Featured",
"categories": [{
"id": "denim-collections-signature-stitch",
"name": "Big T & Super T Stitch",
"categories": []
}, {
"id": "denim-collections-lighten-up",
"name": "Light Wash Denim",
"categories": []
}, {
"id": "dark-wash-denim",
"name": "Dark Wash Denim",
"categories": []
}]
}]
}]
}]
};
console.log(getIds(rawData.categories));
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added in the snippet above.
If you're not afraid of reference loops (shouldn't technically happen in a serialized REST response) you can try recurring function as the simplest way to achieve this
function getIDs(node, isRoot = false) {
if (!node.categories.length) // if I understood your question correctly, you don't want parents to be printed out, otherwise just check for isRoot instead
return isRoot || console.log(node.id);
// with above you won't access non-existent id of the root collection
// because it will stop checking after first true statement
for (const category of categories)
getIDs(category);
}
getIDs(collection, true);
this is example of data from my API look like.
const data = [{
"id": "1",
"name": "Lesley",
"creationDate": "2019-11-21 20:33:49.04",
},
{
"id": "2",
"name": "Claude",
"creationDate": "2019-11-21 20:33:09.397",
},
{
"id": "3",
"name": "Lesley",
"creationDate": "2019-11-20 20:31:46.357",
{
"id": "4",
"name": "Yin Sun Shin",
"creationDate": "2019-11-20 23:13:40.41",
},
{
"id": "5",
"name": "Claude",
"creationDate": "2019-11-21 23:13:30.18",
},
{
"id": "6",
"name": "Moskov",
"creationDate": "2019-11-20 23:10:22.863",
},
{
"id": "7",
"name": "Lesley",
"creationDate": "2019-11-19 01:15:26.457",
},
{
"id": "8",
"name": "Yin Sun Shin",
"creationDate": "2019-11-19 19:39:32.233",
},
{
"id": "9",
"name": "Claude",
"creationDate": "2019-11-18 19:38:54.117",
}]
i have a list of data that need to display all information in vue-ant-design list. but there is too much of data that make the system lagging. i'm intended filter this data before being displayed. i've tried some other javascript function to display the latest date data but not succeed. is there any javascript reference that i can refer or any sharing that i can refer for how to filter this API data with the latest date in the creationDate? i've no more idea on how to filter this data.
The best will be to get the data from the API ready to show..
But, with JavaScript in the frontend you can do:
Sort by creationDate DESC
Filter elements with creationDate.substring(0, 10) equal to first element's creationDate.substring(0, 10) in the sorted array
Code:
const data = [{ "id": "1", "name": "Lesley", "creationDate": "2019-11-21 20:33:49.04", }, { "id": "2", "name": "Claude", "creationDate": "2019-11-21 20:33:09.397", }, { "id": "3", "name": "Lesley", "creationDate": "2019-11-20 20:31:46.357", }, { "id": "4", "name": "Yin Sun Shin", "creationDate": "2019-11-20 23:13:40.41", }, { "id": "5", "name": "Claude", "creationDate": "2019-11-21 23:13:30.18", }, { "id": "6", "name": "Moskov", "creationDate": "2019-11-20 23:10:22.863", }, { "id": "7", "name": "Lesley", "creationDate": "2019-11-19 01:15:26.457", }, { "id": "8", "name": "Yin Sun Shin", "creationDate": "2019-11-19 19:39:32.233", }, { "id": "9", "name": "Claude", "creationDate": "2019-11-18 19:38:54.117", }]
const result = data
.sort((a, b) => new Date(b.creationDate) - new Date(a.creationDate))
.filter((a, _, arr) => a.creationDate.substring(0, 10) === arr[0].creationDate.substring(0, 10))
console.log(result)
I've got an array of objects and I need to get their positions in the array where the key ecommerce_order_number value matches the number im searching for.
Ive tried doing a for loop, but I can see that this isnt a good idea as there may be 500 + checks im doing against an array of order numbers i have that is seperate.
Usually I would just loop through and get all the matches and continue to get out of there. but Im hoping there is a cleaner approach using vanilla javascript.
var myTransactions = [];
myTransactions[0].order = 'S17243';
for(i=0; i < myTransactions.length; i++)
{
//
}
but I can see my looping would be limited to the number of transaction count, and if there are more payments compared to the number of transactions which does happen, i wont be able to obtain all the indexes of the payments array that match.
Is there a function that will search an array of object and return the indexes of all keys found to match a particular string ?
var payments= [{
"id": "11419",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Angela smith",
"id": "6641"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3810.2,
"ecommerce_order_number": "S17247",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11420",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Paul Georgeson",
"id": "6640"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3539,
"ecommerce_order_number": "S17223",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11421",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Leanne Smithy",
"id": "6638"
},
"account": {
"name": "test-data",
"id": "336"
},
"amount": 1617.2,
"ecommerce_order_number": "S17243",
"datecreated": "10/4/2017 5:42 PM"
}
}];
I had a similar situation and i did it using Array.map.
var payments= [{
"id": "11419",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Angela smith",
"id": "6641"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3810.2,
"ecommerce_order_number": "S17247",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11420",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Paul Georgeson",
"id": "6640"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3539,
"ecommerce_order_number": "S17223",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11421",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Leanne Smithy",
"id": "6638"
},
"account": {
"name": "test-data",
"id": "336"
},
"amount": 1617.2,
"ecommerce_order_number": "S17243",
"datecreated": "10/4/2017 5:42 PM"
}
}];
var arrOfIndexes = payments.map((payment, index, completeArr) => {
if(payment.cols.ecommerce_order_number === "S17243") {
return index;
} else { return null }
}).filter(Boolean); // filter used to remove falsey values
console.log(arrOfIndexes);
var payments= [{
"id": "11419",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Angela smith",
"id": "6641"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3810.2,
"ecommerce_order_number": "S17247",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11420",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Paul Georgeson",
"id": "6640"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3539,
"ecommerce_order_number": "S17223",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11421",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Leanne Smithy",
"id": "6638"
},
"account": {
"name": "test-data",
"id": "336"
},
"amount": 1617.2,
"ecommerce_order_number": "S17243",
"datecreated": "10/4/2017 5:42 PM"
}
}];
var ids=payments.reduce((arr,el,i)=>(el.cols&&el.cols.ecommerce_order_number.includes("S17243")&&!arr.push(i))||arr,[]);
You could use the Array.prototype.reduce method...
Longform:
var ids=payments.reduce((arr,el,i)=>{
if(el.cols&&el.cols.ecommerce_order_number.includes("S17243")) arr.push(i);
return arr;
},[]);
http://jsbin.com/jucexilude/edit?console
You could use the jQuery grep function in order to retrieves all the objects with a specific attribute value, then you could get only the id if you need, see following please:
Get all the objects with ecommerce_order_number = "S17243":
var filteredObj = $.grep(payments, function(obj) {
return obj.cols.ecommerce_order_number === "S17243";
});
Get only the ids of the above objects:
var onlyIds = filteredObj.map(function(obj) {return obj.id;});
Combine the above codes in one line instructions:
var oneLineObj = $.grep(payments, function(obj) {
return obj.cols.ecommerce_order_number === "S17243";
}).map(function(obj) {return obj.id;});
See following example please:
var payments= [{
"id": "11419",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Angela smith",
"id": "6641"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3810.2,
"ecommerce_order_number": "S17247",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11420",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Paul Georgeson",
"id": "6640"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3539,
"ecommerce_order_number": "S17223",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11421",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Leanne Smithy",
"id": "6638"
},
"account": {
"name": "test-data",
"id": "336"
},
"amount": 1617.2,
"ecommerce_order_number": "S17243",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "test",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Alessandro",
"id": "1"
},
"account": {
"name": "test-data",
"id": "336"
},
"amount": 5000.2,
"ecommerce_order_number": "S17243",
"datecreated": "18/5/2017 5:42 PM"
}
}];
var filteredObj = $.grep(payments, function(obj) {
return obj.cols.ecommerce_order_number === "S17243";
});
var onlyIds = filteredObj.map(function(obj) {return obj.id;});
console.log("IDS: ", onlyIds);
console.log("COMPLETE OBJECTS: ", filteredObj);
var oneLineObj = $.grep(payments, function(obj) {
return obj.cols.ecommerce_order_number === "S17243";
}).map(function(obj) {return obj.id;});
console.log(oneLineObj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Pure javascript, no jquery solution.
You could use new array helpers: .filter or .find.
.filter solution if you expect to have more than one results.
const resultFiler = payments.filter(payment => {
if (payment.cols.ecommerce_order_number === searchValue) {
return payment;
}
}).map(payment => payment.id);
.filter helper only returns complete array element. We could not do something like return payment.id which would be ideal in our case, because we only care about .id property.
To get .id poperty we used .map(payment => payment.id);.
.find solution if you expect only one result.
const resultFind = payments.find(payment => {
if (payment.cols.ecommerce_order_number === searchValue) {
return payment;
}
}).id;
If you are not familiar with fat arrow/ES6 syntax here is equivalent code:
var resultFiler = payments.filter(function (payment) {
if (payment.cols.ecommerce_order_number === searchValue) {
return payment;
}
}).map(function (payment) {
return payment.id;
});
// Using find
var resultFind = payments.find(function (payment) {
if (payment.cols.ecommerce_order_number === searchValue) {
return payment;
}
}).id;
See working example.
var payments= [{
"id": "11419",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Angela smith",
"id": "6641"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3810.2,
"ecommerce_order_number": "S17247",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11420",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Paul Georgeson",
"id": "6640"
},
"account": {
"name": "test-data",
"id": "335"
},
"amount": 3539,
"ecommerce_order_number": "S17223",
"datecreated": "10/4/2017 5:42 PM"
}
}, {
"id": "11421",
"recordtype": "payment",
"cols": {
"entity": {
"name": "Leanne Smithy",
"id": "6638"
},
"account": {
"name": "test-data",
"id": "336"
},
"amount": 1617.2,
"ecommerce_order_number": "S17243",
"datecreated": "10/4/2017 5:42 PM"
}
}];
const searchValue = "S17243"
// Find all matching occurrences
const resultFiler = payments.filter(payment => {
if (payment.cols.ecommerce_order_number === searchValue) {
return payment;
}
}).map(payment => payment.id);
// Using find
const resultFind = payments.find(payment => {
if (payment.cols.ecommerce_order_number === searchValue) {
return payment;
}
}).id;
console.log(resultFiler);
console.log(resultFind);
I have a json file returned on my javascript code. The file looks like this :
{
"data": [
{
"id": "594984240522886",
"from": {
"id": "593959083958735",
"category": "Community",
"name": "Decoc"
},
"name": "Ducks",
"description": "ducks",
"link": "http://www.facebook.com/album.php?fbid=594984240522886&id=593959083958735&aid=1073741834",
"cover_photo": "594984260522884",
"count": 4,
"type": "normal",
"created_time": "2013-06-13T15:12:22+0000",
"updated_time": "2013-06-13T15:12:40+0000",
"can_upload": false
},
{
"id": "593963787291598",
"from": {
"id": "593959083958735",
"category": "Community",
"name": "Decoc"
},
"name": "Profile Pictures",
"link": "http://www.facebook.com/album.php?fbid=593963787291598&id=593959083958735&aid=1073741832",
"cover_photo": "593963797291597",
"count": 1,
"type": "profile",
"created_time": "2013-06-11T16:52:29+0000",
"updated_time": "2013-06-11T16:52:31+0000",
"can_upload": false
},
{
"id": "593963467291630",
"from": {
"id": "593959083958735",
"category": "Community",
"name": "Decoc"
},
"name": "Goats",
"description": "goats",
"link": "http://www.facebook.com/album.php?fbid=593963467291630&id=593959083958735&aid=1073741831",
"cover_photo": "593963477291629",
"count": 7,
"type": "normal",
"created_time": "2013-06-11T16:51:56+0000",
"updated_time": "2013-06-11T16:52:02+0000",
"can_upload": false
},
{
"id": "593962700625040",
"from": {
"id": "593959083958735",
"category": "Community",
"name": "Decoc"
},
"name": "Dogs",
"description": "dogs",
"link": "http://www.facebook.com/album.php?fbid=593962700625040&id=593959083958735&aid=1073741830",
"cover_photo": "593962710625039",
"count": 10,
"type": "normal",
"created_time": "2013-06-11T16:50:27+0000",
"updated_time": "2013-06-11T16:50:37+0000",
"can_upload": false
},
{
"id": "593961937291783",
"from": {
"id": "593959083958735",
"category": "Community",
"name": "Decoc"
},
"name": "Cows",
"description": "Cows",
"link": "http://www.facebook.com/album.php?fbid=593961937291783&id=593959083958735&aid=1073741829",
"cover_photo": "593961983958445",
"count": 5,
"type": "normal",
"created_time": "2013-06-11T16:48:26+0000",
"updated_time": "2013-06-11T16:49:32+0000",
"can_upload": false
}
],
"paging": {
"cursors": {
"after": "NTkzOTYxOTM3MjkxNzgz",
"before": "NTk0OTg0MjQwNTIyODg2"
}
}
}
I would like to loop inside the "data" and see how many different data elements exist(as you see each element has an id , from , name , description..) . How can i do that with javascript?
You can try the following code:
for(i=0;json.data.length;i++){
var element = json.data[i];
}
or also in this other way:
for (i in json.data) {
if (json.data.hasOwnProperty(i)) {
var element = json.data[i];
}
}