Find value of an object in json, node.js - javascript

I need a way to find the kills and deaths (etc.) of the corresponding name that is inputted, and if the name is not in the object I need it to output something too.
Something like this:
if (medic does not have(name)) return;
const kills = medic.(name).kills
Sample JSON:
{
"assault": {
"general": {
"kills": 1134,
"deaths": 1122,
"abc": "123"
},
"list": {
"A": {
"name": "name1",
"kills": 12,
"deaths": 120
},
"B": {
"name": "name2",
"kills": 23,
"deaths": 53
}
}
},
"support": {
"general": {
"kills": 123,
"deaths": 11232,
"abc": "11233"
},
"list": {
"A": {
"name": "name4",
"kills": 12,
"deaths": 120
},
"B": {
"name": "name5",
"kills": 23,
"deaths": 53
}
}
}
}

First clean your data to get a nice list of the names and info:
const listOfNames = [...Object.values(data.assault.list), ...Object.values(data.support.list)]
Then use the find method on that list to search for a name, with the backup of "Not Found" if the search returns undefined:
const search = (name) => listOfNames.find(item => item.name===name) || "Not Found"
Then you can use that search function elsewhere:
console.log(search("name2")) gives
See it in action here:
https://repl.it/#LukeStorry/62916291

Do you need assault and support to be sum up or all you need is one of those? Is your data always on the same shape? I'm going to assume that it is, and I'll provide both, the sum and the individual one:
const data = // your JSON here
const getAssaultKills = name => (data.assault.list[name] || {kills: 0}).kills
const getSupportKills = name => (data.support.list[name] || {kills: 0}).kills
const getTotalKills = name =>
getSupportKills(name) + getAssaultKills(name)
getTotalKills("A") // => 24
getTotalKills("C") // => 0

Related

JavaScript Logic App action error "Parsing code failed. Unexpected token ...'.'."

(These are just a dummy datasets. Real datasets are big, and have 900 records in each datasets) I have two array datasets in my Logic App:
Dataset1:
[
{
"userId": "123",
"name": "Victor"
},
{
"userId": "456",
"name": "Jack"
},
{
"userId": "789",
"name": "Winston"
}
]
Datset2:
[
{
"userId": "123",
"age": "75"
},
{
"userId": "456",
"age": "72"
}
]
I want to apply a left join in Logic App and generate a final output:
{
"userId": "123",
"name": "Victor",
"age": "75"
},
{
"userId": "456",
"name": "Jack",
"age": "72"
},
{
"userId": "789",
"name": "Winston",
"age": null
}
]
First I applied a For Each loop and condition using native Logic App actions, which works fine but since the datasets are large, it takes around 3 hours to complete. So I applied a below Inline JavaScript code in Logic App.
const dataset1 = [
{
"userId": "123",
"name": "Victor"
},
{
"userId": "456",
"name": "Jack"
},
{
"userId": "789",
"name": "Winston"
}
]
const dataset2 = [
{
"userId": "123",
"age": "75"
},
{
"userId": "456",
"age": "72"
}
]
const output = dataset1.map(x => {
const result = dataset2.find(element => element.userId === x.userId);
return {...x, age: result?.age || null};
})
console.log(output)
When I run this code outside of Logic App, it works fine but when I run it from the inside the Logic App JavaScript action, it does not let me save the Logic App and throws below error:
Failed to save logic app logic-test. 'The input parameter 'code' for inline code action 'Execute_JavaScript_Code' contains invalid code. Parsing the code failed with error 'Line 29: Unexpected token ...'.'. Status code: 'BadRequest'.
i think you just forget parenthesis in you inline function
const output = dataset1.map((x) => {
const result = dataset2.find((element) => element.userId === x.userId);
return { ...x, age: result?.age || null };
});
result:
try this
return result === undefined ? { ...x, age: "null" } : { ...x, ...result };
but dont give me a negative point i'm trying to help

How do I set value of nested object to key of current object?

This array has the key to substitute with nested key of 'name'
const arr = ['status', 'user', ...] <-- This array contains key to be replaced with name
This is what my current response object is
[
{
"id": 11,
"location": "Mumbai",
"status": {
"name": "NEW"
},
"user": {
"name": "Rakesh"
}
}
]
How do I modify the above array of objects to this below
[
{
"id": 11,
"location": "Mumbai",
"status": "NEW",
"user": "Rakesh"
}
]
can try below code
const keys = ['status', 'user']
let arr = [
{
"id": 11,
"location": "Mumbai",
"status": {
"name": "NEW"
},
"user": {
"name": "Rakesh"
}
}
]
arr.map(a => keys.forEach(k => {
if(a[k] && a[k].name) a[k] = a[k].name
}));
console.log(arr);
I'd try this one:
const results = [
{
"id": 11,
"location": "Mumbai",
"status": {
"name": "NEW"
},
"user": {
"name": "Rakesh"
}
}, {
"id": 12,
"location": "Helsinki",
"status": {
"name": "NEW"
},
"user": {
"name": "Samuli"
}
}
];
const flattenObject = ([key, value]) => ((typeof value === 'object') ? {[key] : value[Object.keys(value)[0]]} : {[key]: value});
const reduceToSingleObject = (acc, b) => ({...acc, ...b});
const actualResults = results.map((result) => Object.entries(result).map(flattenObject).reduce(reduceToSingleObject));
console.log(actualResults);
Explanation:
flattenObject is a function to flatten structure of object inside object. This only takes the first prop (without knowing the name of the key). If you, for some reason, would need to flatten several key-values, then it'd need whole different kind of helper function to sort that out.
reduceToSingleObject is a function to put all the key-value pairs into a single object. This could have been done already in flattenObject function, but for the clarity, I separated it to a normal map - reduce pattern.
actualResults is the outcome where we go through all the entries of your original results.

Check if array of objects, which also contain nested arrays with objects, are the same, if so, combine them into one object and add the keys together

I would need to check if the objects in the "food" array are equal to each other, and the ones that are - combine into one adding amount and mody.amount and leaving the rest unchanged. This is just for better order data displaying. I tried with lodash library and reduce but but I don't know exactly how to construct this function that nested objects(mody) adds values ​​as well, and in case isEqual returns false keep the object while concurrently concatenating the identical ones.
What I tried:
obj1.reduce((prev, next) => _.isEqual(prev, next) ? {...prev, amount: prev.amount + next.amount} : next
Now it looks like that:
const food = [
{
"id": 1,
"name": "chicken",
"price": 6,
"amount": 1,
"mody": [
{
"id": 33,
"name": "cheese",
"price": 1,
"amount": 1
},
{
"id": 34,
"name": "chips",
"price": 2,
"amount": 1
}
]
},
{
"id": 1,
"name": "chicken",
"price": 6,
"amount": 1,
"mody": [
{
"id": 33,
"name": "cheese",
"price": 1,
"amount": 1
},
{
"id": 34,
"name": "chips",
"price": 2,
"amount": 1
}
]
},
{
"id": 2,
"name": "pizza",
"price": 6,
"amount": 2,
"mody": [
{
"id": 12,
"name": "extra cheese",
"price": 2,
"amount": 1
}
]
}
]
and would need something like that:
const food = [
{
"id": 1,
"name": "chicken",
"price": 6,
"amount": 2,
"mody": [
{
"id": 33,
"name": "cheese",
"price": 1,
"amount": 2
},
{
"id": 34,
"name": "chips",
"price": 2,
"amount": 2
}
]
},
{
"id": 2,
"name": "pizza",
"price": 6,
"amount": 2,
"mody": [
{
"id": 12,
"name": "extra cheese",
"price": 2,
"amount": 1
}
]
}
]
The algorithm to sum the food amounts and mody amounts are almost the same, the difference is that for each food that has the same id we will sum the mody amount. To make the algorithm simpler I used a dictionary as the accumulator on the reduce function so we have a unique element per key. This element will be our final food or mody with the amount sum.
Mody sum algoritm:
const sumMody = (modyAccumulator, currentMody) => {
//Get the stored mody in the accumulator dictionary or null if it the mody is not stored
const storedMody = modyAccumulator[currentMody.id] ?? null
// if mody is null then add mody to the dictionary using its id as key
if (!storedMody) {
modyAccumulator[currentMody.id] = currentMody
} else {
//Mody is stored then sum amount
storedMody.amount += currentMody.amount
}
return modyAccumulator
}
The food sum algoritm is the same as the sumMody, the only difference is that it calls the sumMody function when the foods are equal:
const sumFood = (foodAccumulator, currentFood) => {
//Get the stored foodin the accumulator dictionary or null if it the food is not stored
const storedFood = foodAccumulator[currentFood.id] ?? null
// if food is null then add food to the dictionary using its id as key
if (!storedFood) {
foodAccumulator[currentFood.id] = currentFood
} else {
//Food is stored then sum food amount
storedFood.amount += currentFood.amount
//Create a list with mody from both foods
const modyList = [...storedFood.mody, ...currentFood.mody]
//Use reduce passing the sumMody callback function and initialize the accumulator with a dictionary
const modySumDictionary = modyList.reduce(sumMody, {})
/* The function above return a dictionary where the identifier is the mody.id
and the value is the mody. We only need the values from that dictionary so
we use Object.values to extract all the values. */
storedFood.mody = Object.values(modySumDictionary)
}
return foodAccumulator
}
To execute both sums:
//As explained before the reduce function will return a dictionary so we use Object.values to get only the values
const result = Object.values(food.reduce(sumFood, {}))
console.log(result)
Algoritm without comments:
const sumMody = (modyAccumulator, currentMody) => {
const storedMody = modyAccumulator[currentMody.id] ?? null
if (!storedMody) {
modyAccumulator[currentMody.id] = currentMody
} else {
storedMody.amount += currentMody.amount
}
return modyAccumulator
}
const sumFood = (foodAccumulator, currentFood) => {
const storedFood = foodAccumulator[currentFood.id] ?? null
if (!storedFood) {
foodAccumulator[currentFood.id] = currentFood
} else {
storedFood.amount += currentFood.amount
const modyList = [...storedFood.mody, ...currentFood.mody]
const modySumDictionary = modyList.reduce(sumMody, {})
storedFood.mody = Object.values(modySumDictionary)
}
return foodAccumulator
}
const result = Object.values(food.reduce(sumFood, {}))
console.log(result)
Reference to Object.values

JavaScript Mapping Object To Array

I would like to convert objects in JavaScript, but I'm not really sure of the best way to do it. I don't often code in the language so I don't really know much of the fundamentals- this is the object I get back from an API call in a React project:
{
"api": {
"results": 380,
"fixtures": [
{
"fixture_id": 65,
"league_id": 2,
"league": {
"name": "Premier League",
"country": "England",
"logo": "https://media.api-sports.io/football/leagues/2.png",
"flag": "https://media.api-sports.io/flags/gb.svg"
},
"event_date": "2018-08-10T19:00:00+00:00",
"event_timestamp": 1533927600,
"firstHalfStart": 1533927600,
"secondHalfStart": 1533931200,
"round": "Regular Season - 1",
"status": "Match Finished",
"statusShort": "FT",
"elapsed": 90,
"venue": "Old Trafford (Manchester)",
"referee": null,
"homeTeam": {
"team_id": 33,
"team_name": "Manchester United",
"logo": "https://media.api-sports.io/football/teams/33.png"
},
"awayTeam": {
"team_id": 46,
"team_name": "Leicester",
"logo": "https://media.api-sports.io/football/teams/46.png"
},
"goalsHomeTeam": 2,
"goalsAwayTeam": 1,
"score": {
"halftime": "1-0",
"fulltime": "2-1",
"extratime": null,
"penalty": null
}
}
]
}
}
I would like to convert it to this array (the array holds multiple objects):
[
{
"homeTeam": {
"id": 33,
"name": "Manchester United",
"teamId": 33
},
"awayTeam": {
"id": 46,
"name": "Leicester",
"teamId": 46
},
"outcome": {
"goalsScoredByAwayTeam": 2,
"goalsScoredByHomeTeam": 1
},
"resulted": true,
"type": "LEAGUE"
}
]
The teamId and id actually need to lookup another object before the final output.
I'm not sure what the best way to do it is. This is my function so far, trying to make use of optional chaining:
function convertFixturesToArray() {
fixturesStore.getFixtures()?.api?.fixtures?.length ? fixtures.api.fixtures.map(fixture => (
//TRANSFORMATION GOES IN HERE
)) : null;
}
You seem on the right track. It should be something like this (written in a slightly more modern JS)
convertFixturesToArray = () => fixturesStore.getFixtures()?.api?.fixtures?.map?.(fixture => {
//Do whatever check you need here with the fixture object
return {
homeTeam: { ...fixture.homeTeam },
awayTeam: { ...fixture.awayTeam },
outcome: {
goalsScoredByAwayTeam: fixture.goalsAwayTeam,
goalsScoredByHomeTeam: fixture.goalsHomeTeam,
},
type: 'LEAGUE',
resulted: true,
},
}) ?? [];
It looks like you're trying to get certain key/value pairs from your api response. With a mix of map, reduce, and find, you can get the values you're looking for by defining them in an array (i.e. desiredProps).
Of course, adding the "outcome" field and your other hardcoded fields would require a bit more logic on top of this. Boris' answer addresses this problem. I've taken a more flexible approach.
let apiResult = {
"fixtures": [
{
"prop1": "a1",
"prop2": "a2",
"prop3": "a3"
},
{
"prop1": "b1",
"prop2": "b2",
"prop3": "b3"
}
]
}
let desiredProps = ["prop2", "prop3"]
let result = apiResult.fixtures.map(x => {
return Object.keys(x).reduce((acc, curr) => {
if (desiredProps.find(y => y === curr)) {
acc[curr] = x[curr]
}
return acc
}, {})
})
console.log(result)

Group the data in an array and get the sum from the array of object values

I am new to react and javascript. Here I am trying to use the lodsh function.
I have an array of object which looks like ,
const data = [{
"Id": "1",
"testone": 100,
"test": 40,
"Original": {
"Id": "11"
},
"__Parent__": {
"Id": "20",
"Status": "INP"
}
}, {
"Id": "2",
"testone": 120,
"test": 20,
"Original": {
"Id": "10"
},
"__Parent__": {
"Id": "21",
"Status": "Book"
}
},{
"Id": "3",
"testone": 110,
"test": 140,
"Original": {
"Id": "11"
},
"__Parent__": {
"Id": "20",
"Status": "INP"
}
}, {
"Id": "4",
"testone": 100,
"test": 40,
"Original": {
"Id": "11"
},
"__Parent__": {
"Id": "20",
"Status": "Val"
}
}]
Here, I have one function which has the product Id . which I am passing from another function =>
cont value = (PID, data) => {
}
So, this function ,
I need do sum , where first I need to take all the object which has the same Id as PID. The Id from object is to be Original.ID. If these matches then after that ,I need to check the status of that objects like , is status is either INP or BOOK then for summation need to take the
testone key value or else need to take the `test` key value.
So, In the given example it will be like ,
Id is 11 which is passed to a function and in the given object 3 objects where it matches.
Now,
while returning sum it will be like ,
100 + 100 + 40 which will be 240.
So, How do I do this . thanks .
I think it's best to do it with Array.reduce if you support IE9 and after.
const sum = data.reduce((total, item) => {
if (item.Original.Id !== PID) return total;
const { status, testone, test } = item;
let addition = 0;
if (status === "INP") addition = testone;
else if (status === "BOOK") addition = test;
return total + addition;
}, 0);

Categories