Sorting Arrays creating key value pairs from multiple sources - javascript

I have a large JSON array that I want to use to create key value pairs, combining 3 integers as one pair item and another integer for the second pair item.
I am a begginer in coding so looking for some good advice along the way. The purpose of the code is to integrate in to my automation setup.
Im trying to put showid, season and episode as one combined integer and the episodeid and the key value pair.
So for the example below :
newarray = [{7.2.1 : 272, 7.2.2 : 273}]
2 objects within the array are as follows :
[
{
"episodes": [
{
"art": {
"season.banner": "image://.jpg/",
"season.poster": "image://.jpg/",
"season.thumb": "image:.tbn/",
"tvshow.banner": ".jpg/",
"tvshow.fanart": "image:jpg/",
"tvshow.poster": "image:jpg/"
},
"episode": 1,
"episodeid": 272,
"file": "test.avi",
"label": "test1",
"originaltitle": "",
"playcount": 0,
"plot": Hello World",
"rating": 8,
"season": 2,
"thumbnail": "image.tbn/",
"title": "test1",
"tvshowid": 7
},
{
"art": {
"season.banner": "image://.jpg/",
"season.poster": "image://.jpg/",
"season.thumb": "image:.tbn/",
"tvshow.banner": ".jpg/",
"tvshow.fanart": "image:jpg/",
"tvshow.poster": "image:jpg/"
},
"episode": 2,
"episodeid": 273,
"file": "test1.avi",
"label": "test1",
"originaltitle": "",
"playcount": 0,
"plot": Hello World",
"rating": 8,
"season": 2,
"thumbnail": "image1.tbn/",
"title": "test2",
"tvshowid": 7
},
]
I have tried to sort using push but its too basic for my needs. Can anyone help?

You can simply map over each show, then map over each episode, then use a template string to create the key of each object:
shows = [{
"episodes": [
{"episode": 1, "episodeid": 272, "season": 2, "tvshowid": 7 },
{"episode": 2, "episodeid": 273, "season": 2, "tvshowid": 7 }
]
}]
const mapped = shows.map(show => show.episodes.map(o => ({
[`${o.tvshowid}.${o.season}.${o.episode}`]: o.episodeid
})))
console.log(mapped)

You can use a reducer to get the an array of relations:
const collection =
{
"episodes": [
{
"art": {
"season.banner": "image://.jpg/",
"season.poster": "image://.jpg/",
"season.thumb": "image:.tbn/",
"tvshow.banner": ".jpg/",
"tvshow.fanart": "image:jpg/",
"tvshow.poster": "image:jpg/"
},
"episode": 1,
"episodeid": 272,
"file": "test.avi",
"label": "test1",
"originaltitle": "",
"playcount": 0,
"plot": "Hello World",
"rating": 8,
"season": 2,
"thumbnail": "image.tbn/",
"title": "test1",
"tvshowid": 7
},
{
"art": {
"season.banner": "image://.jpg/",
"season.poster": "image://.jpg/",
"season.thumb": "image:.tbn/",
"tvshow.banner": ".jpg/",
"tvshow.fanart": "image:jpg/",
"tvshow.poster": "image:jpg/"
},
"episode": 2,
"episodeid": 273,
"file": "test1.avi",
"label": "test1",
"originaltitle": "",
"playcount": 0,
"plot": "Hello World",
"rating": 8,
"season": 2,
"thumbnail": "image1.tbn/",
"title": "test2",
"tvshowid": 7
},
]
}
relations = collection.episodes.reduce((acc, curr) => {
const relation = {[curr.tvshowid + '.' + curr.season + '.' + curr.episode]: curr.episodeid}
acc = [...acc,relation];
return acc;
},[])
console.log(relations)

You could use map for creating a new array.
var newarray = oShows.episodes.map( function(o){
return {[o.tvshowid + "." + o.season + "." + o.episode] : o.episodeid};
});
console.log(newarray); //[{7.2.1: 272}, {7.2.2: 273}]
Im trying to put showid, season and episode as one combined integer...
That's not possible because e.g. "7.2.1" is no integer. Your key will be a string.

Related

Core Javascript Question -- Delete Object in a json file sourced from a column if conditions meet

the reason I need the code to work in core javascript is the tool we use, it uses Rhino from mozilla, so it cannot contain objects or methods related to manipulation of web pages.
I am trying to compare data from two json files using core javascript, When the order_number and extid is same we compare the count(fullfilments.line_items) and quantity(which is the sum of all the quantities of all line items under that fulfillment, fullfilments.line_items.quantity) . If the order_number and ext_id combination match along with count and sum above, do nothing. If no match, we remove the refund. the code works fine in Visual Studio. I am new to pentaho and I think the code needs to be changed as only core js works with this tool.
In the Orders file are sample json structure, for example Order_number (66 in this case) need to calculate and compare the count of line items(6 in this case) along with the Quantity of items(7 in this case), if it doesn't match need to remove Object Refund along with its elements, else No Changes.
``````Sample File````````
[
{
"app_id": 111,
"fulfillments":
[
{
"id": 39828,
"order_id": 450625,
"receipt": {},
"service": "manual",
"shipment_status": null,
"status": "success",
"updated_at": "2022-05-24",
"line_items":
[{
"id": 376,
"quantity": 2
},
{
"id": 992,
"quantity": 1
},
{
"id": 929,
"quantity": 1
},
{
"id": 768,
"quantity": 1
},
{
"id": 929,
"quantity": 1
},
{
"id": 768,
"quantity": 1
}
]
}
],
"line_items": [],
"name": "#59",
"number": 6,
"order_number": 66,
"ext_id": 110,
"refunds": [
{
"id": 80,
"created_at": "2000-06-17T14:31:06-04:00"
}
]
},
{
"app_id": 111,
"fulfillments": [
{
"id": 398000,
"order_id": 450005,
"receipt": {},
"service": "manual",
"shipment_status": null,
"status": "success",
"updated_at": "2022-05-24",
"line_items":
[{
"id": 376,
"quantity": 2
},
{
"id": 992,
"quantity": 1
},
{
"id": 929,
"quantity": 1
},
{
"id": 768,
"quantity": 1
}
]
}
],
"line_items": [],
"name": "#59",
"number": 6,
"order_number": 67,
"ext_id": 114,
"refunds": [
{
"id": 81,
"created_at": "2000-06-17T14:31:06-04:00"
}
]
},
{
"app_id": 111,
"fulfillments": [
{
"id": 39828,
"order_id": 450625,
"receipt": {},
"service": "manual",
"shipment_status": null,
"status": "success",
"updated_at": "2022-05-24",
"line_items":
[{
"id": 376,
"quantity": 2
},
{
"id": 768,
"quantity": 1
},
{
"id": 929,
"quantity": 2
},
{
"id": 768,
"quantity": 2
}
]
}
],
"line_items": [],
"name": "#59",
"number": 6,
"order_number": 68,
"ext_id": 113,
"refunds": [
{
"id": 80,
"created_at": "2000-06-17T14:31:06-04:00"
}
]
}
]
```````````````````````````````json`````````````
//resultset file content
[
{
"order_number": 66,
"extid":110,
"line_items_count": 6,
"quantity": 7
},
{
"order_number": 67,
"extid":114,
"line_items_count": 4,
"quantity": 7
},
{
"order_number": 68,
"extid":113,
"line_items_count": 4,
"quantity": 6
}
]
`````````````````````````````````````````````````Code`````````````````
/**
* orders.json file has some sample orders
* resultset.json file has results from sql Lookup to the orders.
*
*/
const orders = require('./orders.json');
function compare(order) {
let isMatched = false;
let resultSet = require('./resultset.json');
let result = resultSet.find(function (item) {
return item.order_number === order.order_number;
});
if (
result &&
result.line_items_count === order.items &&
result.quantity === order.quantity
) {
isMatched = true;
}
return isMatched;
}
function fixOrders(orders) {
orders.map(function (order) {
let { order_number, line_items } = order;
let quantity = line_items.reduce(function (quantity, line_item) {
return (quantity += line_item.quantity);
}, 0);
if (!compare({ order_number, items: line_items.length, quantity })) {
delete order.refunds;
}
});
return orders;
}
let fixedOrders = fixOrders(orders);
console.log(fixedOrders);
// store in output.js
//========================================
// var fs = require('fs');
// fs.writeFile('outputFile.json', JSON.stringify(fixedOrders), (err) => {
// if (err) console.log(err);
// else {
// console.log('File written successfully\n');
// // console.log('The written has the following contents:');
// // console.log(fs.readFileSync('outputFile.json', 'utf8'));
// }
// });
[PDI Flow][1]
[1]: https://i.stack.imgur.com/3OzQE.png

Transform array of data into grouped data for SectionList component

I'll freely admit that Javascript is not my strongest language, and React Native is very new, so, there may be an obviously easy way to do this that I'm not seeing.
I've got an API that presents some transaction data in a simple structure:
[
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
I want to present this data using a SectionList component, with the transactions in sections by date. My (likely crude) attempt to solve this was going to be to transform this data into the following structure:
[
{
"date": "2021-09-10",
"transactions": [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
}
]
},
{
"date": "2021-09-09",
"transactions": [
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
}
]
},
{
"date": "2021-09-07",
"transactions": [
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
}
]
But I'm honestly lost as to how to transform this data (or if there's a better way to solve this problem). I started by using Lodash's groupBy function, which seemed promising, but it looks like SectionList doesn't want an object, it wants an array.
Transforming the output of groupBy into an array straight off drops the keys and I've got grouped data but no clear value for the section header.
Again, there's probably some deviously simple way to address this, data comes in as a flat array all the time. I appreciate any guidance, assistance, or examples anybody can point me to.
const input = [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
const result = input.reduce((accum, current)=> {
let dateGroup = accum.find(x => x.date === current.date);
if(!dateGroup) {
dateGroup = { date: current.date, transactions: [] }
accum.push(dateGroup);
}
dateGroup.transactions.push(current);
return accum;
}, []);
console.log(result)
Given an array, whenever your result is expecting to have same number of elements, use map, but since your result has different number of elements, use reduce as shown above. The idea is by having reduce, loop over each element, see if you can find the element, and push the current element into the list
The lodash groupBy just helps you with group data, you should process grouped data by converting it into your format.
const input = [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
];
const groupedArray = _.groupBy(input, "date");
let result = [];
for (const [key, value] of Object.entries(groupedArray)) {
result.push({
'date': key,
'transactions': value
})
}
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
simply
const data =
[ { id: 1, title: 'Apple Store', date: '2021-09-10', amount: '$100.00' }
, { id: 41, title: 'Zulauf, Walter and Metz', date: '2021-09-10', amount: '$14.00' }
, { id: 9, title: 'Aufderhar PLC', date: '2021-09-09', amount: '$78.00' }
, { id: 10, title: 'Bayer and Sons', date: '2021-09-07', amount: '$67.00' }
]
const res = Object.entries(data.reduce((r,{id,title,date,amount})=>
{
r[date] = r[date] ?? []
r[date].push({id,title,date,amount})
return r
},{})).map(([k,v])=>({date:k,transactions:v}))
console.log( res )
.as-console-wrapper { max-height: 100% !important; top: 0 }
With lodash you can group by the date then map to the required form:
const input = [{"id":1,"title":"Apple Store","date":"2021-09-10","amount":"$100.00"},{"id":41,"title":"Zulauf, Walter and Metz","date":"2021-09-10","amount":"$14.00"},{"id":9,"title":"Aufderhar PLC","date":"2021-09-09","amount":"$78.00"},{"id":10,"title":"Bayer and Sons","date":"2021-09-07","amount":"$67.00"}];
const result = _.map(
_.groupBy(input, 'date'),
(transactions, date) => ({ date, transactions })
)
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
you could use loadash
var result = _(data)
.groupBy(item => item.date)
.map((value, key) => ({date: key, transactions: value}))
.value();

Replacing two objects in an array

I am trying to develop a dynamic DraggableFlatList with react native redux, where the updated array from onDragEnd is dispatched to the store. Hence I am trying to create a function where I use the "from" and "to" parameters from the return object from onDragEnd to alter a new array before dispatch. As an example, in the object below, I work with three items, that are objects from the array:
Object {
"data": Array [
Object {
"backgroundColor": "rgb(154, 0, 132)",
"category": "Practical",
"description": "Zero",
"duedate": Object {
"cond": false,
"date": "",
},
"id": 0.7945943069813785,
"iterations": "",
"key": "0",
},
Object {
"backgroundColor": "rgb(120, 5, 132)",
"category": "Practical",
"description": "One",
"duedate": Object {
"cond": false,
"date": "",
},
"id": 0.8857539547977513,
"iterations": "",
"key": "1",
},
Object {
"backgroundColor": "rgb(184, 10, 132)",
"category": "Practical",
"description": "Two ",
"duedate": Object {
"cond": false,
"date": "",
},
"id": 0.11232602853449736,
"iterations": "",
"key": "2",
},
],
"from": 2,
"to": 1,
}
Here I would like the object with the description "two" to change place with the object with the description "one." The keys don't matter because I give them new keys when I render during render.
The function that is doing the replacement looks like this so far:
const dragComplete = (item) => {
let itemArray = item.data;
// from object is going to be replaced with to object and visa vreca
let indexFrom = item.from;
let indexTo = item.to;
let objMovesFrom = itemArray[indexFrom];
let objMovesTo = itemArray[indexTo];
let sortedArray = itemArray;
console.log('Object moves from : ' + objMovesFrom.description);
console.log('Obejct moves to : ' + objMovesTo.description);
sortedArray.map((task, i) => {
if ((i = indexFrom)) {
sortedArray.splice(indexFrom, 1, objMovesTo);
}
if ((i = indexTo)) {
sortedArray.splice(indexTo, 1, objMovesFrom);
}
});
console.log(item);
//dispatch(setTaskList(item.data));
};
I haven't figured to make any sense of it yet...
Thx for the helpful answers!
How about just simply swapping items?..
const dragComplete = item => {
const {
from: sourceIndex,
to: targetIndex,
data: dragList,
} = item;
// // shallow `item.data` copy for a non mutating approach.
// const swapList = Array.from(dragList);
const dragItem = dragList[sourceIndex]; // swapList[sourceIndex];
const swapItem = dragList[targetIndex]; // swapList[targetIndex];
// simply swap items.
// actively mutate `item.data`. // // `item.data` remains unmutated.
dragList[targetIndex] = dragItem; // swapList[targetIndex] = dragItem;
dragList[sourceIndex] = swapItem; // swapList[sourceIndex] = swapItem;
console.log('Object moves from : ' + dragItem.description);
console.log('Object moves to : ' + swapItem.description);
// return swapList;
};
const sample = {
"data": [{
"backgroundColor": "rgb(154, 0, 132)",
"category": "Practical",
"description": "Zero",
"duedate": {
"cond": false,
"date": "",
},
"id": 0.7945943069813785,
"iterations": "",
"key": "0",
}, {
"backgroundColor": "rgb(120, 5, 132)",
"category": "Practical",
"description": "One",
"duedate": {
"cond": false,
"date": "",
},
"id": 0.8857539547977513,
"iterations": "",
"key": "1",
}, {
"backgroundColor": "rgb(184, 10, 132)",
"category": "Practical",
"description": "Two ",
"duedate": {
"cond": false,
"date": "",
},
"id": 0.11232602853449736,
"iterations": "",
"key": "2",
}],
"from": 2,
"to": 1,
};
console.log({ data: sample.data });
dragComplete(sample);
console.log({ data: sample.data });
.as-console-wrapper { min-height: 100%!important; top: 0; }

accessing a json child object not in an array

I'm trying to accessing a json child object which is not in an array. i've tried accessing it with my below script but its not working. i want to be able to access the menuCategory Object
JSON
[
{
"id": 67,
"name": "Wednesday Menu",
"serveDate": "2019-06-12 00:00:00",
"expiryDate": "2019-06-12 16:11:00",
"status": "APPROVED",
"isEnabled": true,
"meals": [
{
"id": 45,
"name": "Waakye, Gari and Wele",
"description": "A very well designed food for all kids",
"image": "",
"mealType": "LUNCH",
"unitPrice": 30,
"status": "ENABLED"
},
{
"id": 46,
"name": "Gari and Beans",
"description": "A very well designed food for all kidsss",
"image": "",
"mealType": "LUNCH",
"unitPrice": 12,
"status": "ENABLED"
}
],
"menuCategory": {
"id": 2,
"name": "hello"
}
}
]
JAVASCRIPT
callEditMenu(parent, content) {
this.modalService.open(content);
this.editMenuCategoryId = parent.menuCategory.id;
}
May be like
const parent = [{"id":67,"name":"Wednesday Menu","serveDate":"2019-06-12 00:00:00","expiryDate":"2019-06-12 16:11:00","status":"APPROVED","isEnabled":true,"meals":[{"id":45,"name":"Waakye, Gari and Wele","description":"A very well designed food for all kids","image":"","mealType":"LUNCH","unitPrice":30,"status":"ENABLED"},{"id":46,"name":"Gari and Beans","description":"A very well designed food for all kidsss","image":"","mealType":"LUNCH","unitPrice":12,"status":"ENABLED"}],"menuCategory":{"id":2,"name":"hello"}}]
console.log(parent[0].menuCategory.id);
If the parent argument in the callEditMenu function is referring to the JSON you included then try parent[0].menuCategory.id
let arr = [{"id":67,"name":"Wednesday Menu","serveDate":"2019-06-12 00:00:00","expiryDate":"2019-06-12 16:11:00","status":"APPROVED","isEnabled":true,"meals":[{"id":45,"name":"Waakye, Gari and Wele","description":"A very well designed food for all kids","image":"","mealType":"LUNCH","unitPrice":30,"status":"ENABLED"},{"id":46,"name":"Gari and Beans","description":"A very well designed food for all kidsss","image":"","mealType":"LUNCH","unitPrice":12,"status":"ENABLED"}],"menuCategory":{"id":2,"name":"hello"}}]
for (let item of arr) {
if (item.hasOwnProperty("menuCategory")) {
console.log(item["menuCategory"]);
}
};
let res = arr.filter((item) => item && item.menuCategory);
console.log(res[0].menuCategory);
In case you need to find it dynamically. Above are two different ways
Considering there would be multiple items in your array of objects, you can iterate through each object to get the menuCategory name as
let obj = [
{
"id": 67,
"name": "Wednesday Menu",
"serveDate": "2019-06-12 00:00:00",
"expiryDate": "2019-06-12 16:11:00",
"status": "APPROVED",
"isEnabled": true,
"meals": [
{
"id": 45,
"name": "Waakye, Gari and Wele",
"description": "A very well designed food for all kids",
"image": "",
"mealType": "LUNCH",
"unitPrice": 30,
"status": "ENABLED"
},
{
"id": 46,
"name": "Gari and Beans",
"description": "A very well designed food for all kidsss",
"image": "",
"mealType": "LUNCH",
"unitPrice": 12,
"status": "ENABLED"
}
],
"menuCategory": {
"id": 2,
"name": "hello"
}
}
];
obj.forEach(elem => {
console.log(elem.menuCategory.name);
});

Retrieve data from nested arrays

How can I retrieve ids from a nested array?
Initially I get such json response and I need to get all ids from all nested arrays.
Anybody can help me out here?
Should I use filter or any of find functions?
An example or explanation could be great.
{
"id": 271,
"name": "anything",
"description": null,
"entries": [
{
"id": "fda2afe0-dfc4-4373-9e50-8b140a46f25e",
"name": "first occurence",
"runs": [
{
"id": 284,
"name": "the element from which I want to get id",
"description": null,
"created_on": 1530627823,
"created_by": 2
},
{
"id": 285,
"name": "element for id 2",
"created_by": 2
},
{
"id": 296,
"name": "element for id 3",
"created_on": 1530710993,
"created_by": 2
}
]
},
{
"id": "a65dd3f0-3fc1-4f93-9123-f5a05ae50703",
"name": "second occurence",
"runs": [
{
"id": 272,
"name": "element for id 4",
"created_by": 2,
},
{
"id": 273,
"created_by": 2,
},
{
"id": 274,
"created_by": 2,
}
]
}
]
}
Assuming you're looking for the deepest IDs (Run IDs), here is an example of how it can be done.
let response = {"id":271,"name":"anything","description":null,"entries":[{"id":"fda2afe0-dfc4-4373-9e50-8b140a46f25e","name":"first occurence","runs":[{"id":284,"name":"the element from which I want to get id","description":null,"created_on":1530627823,"created_by":2},{"id":285,"name":"element for id 2","created_by":2},{"id":296,"name":"element for id 3","created_on":1530710993,"created_by":2}]},{"id":"a65dd3f0-3fc1-4f93-9123-f5a05ae50703","name":"second occurence","runs":[{"id":272,"name":"element for id 4","created_by":2,},{"id":273,"created_by":2,},{"id":274,"created_by":2,}]}]}
function getRunIDs() {
let entries = response['entries'] || []
let runIDs = []
entries.forEach(entry => {
entry['runs'].forEach(run => {
runIDs.push(run['id'])
})
})
return runIDs
}
console.log({ runIDs: getRunIDs() })
Assuming you store that json in some variable, say json,
const ids = json.entries.map(entry => entry.runs.map(run => run.id));
should give you a nested array of the IDs that looks like
[ [ 284, 285, 296 ], [ 272, 273, 274 ] ].
If you wanted this to be in a single dimension list, i.e.
[ 284, 285, 296, 272, 273, 274 ],
you can use concat.apply.
const concatIds = [].concat.apply([], ids);
Filter and find functions would be redundant because you are obtaining all the ids and not specific ones. To solve your problem you can simply just use functions with map . For this example, your object will be called exampleObj in which you can simply do this to get the array of all ids:
exampleObj.entries.map(entryObj => {
return entryObj.runs.map(runObj=>{return runObj.id});
});

Categories