copy from one object, change keys but keep the same values - javascript

Hi I want to copy a JavaScript object that lives in an external json file. It looks like this:
and via the code I want to change the keys on each array without changing the values of it. The values for the last key needs be an array instead of just vales
{ "items": [
{ "namezz": "Bike", "price": 100 },
{ "namezz": "TV", "price": 700 },
{ "namezz": "Album", "price": 10 },
{ "namezz": "Book", "price": 5 },
{ "namezz": "Phone", "price": 500 },
{ "namezz": "Computer", "price": 1000 },
{ "namezz": "Keyboard", "price": 25 }
]
}
It needs to looks like this:
[
{ "name": "Bike", "data": [100] },
{ "name": "TV", "data": [700] },
{ "name": "Album", "data": [10] },
{ "name": "Book", "data": [5] },
{ "name": "Phone", "data": [500] },
{ "name": "Computer", "data": [1000] },
{ "name": "Keyboard", "data": [25] }
]
code that I've tried:
const itemNames = simple.map((xxx) => {
return ("name" + xxx.namezz + "data: [" + xxx.price + "]")
})

You're on the right track with the map() method. The way you've used map() will result in an array of strings. Here's an example of using map() to get the output you requested (new array of objects).
const myObject = {
"items": [{
"namezz": "Bike",
"price": 100
},
{
"namezz": "TV",
"price": 700
},
{
"namezz": "Album",
"price": 10
},
{
"namezz": "Book",
"price": 5
},
{
"namezz": "Phone",
"price": 500
},
{
"namezz": "Computer",
"price": 1000
},
{
"namezz": "Keyboard",
"price": 25
}
]
};
const result = myObject.items.map(x => ({ name: x.namezz, data: [x.price] }));
console.log(result);

Problem with your code is returning string whereas you need a object, i.e
return { name:xxx.namezz , data: [xxx.price] }
Alternatively you can use map and destructuring
let obj = { "items": [{ "namezz": "Bike", "price": 100 },{ "namezz": "TV", "price": 700 },{ "namezz": "Album", "price": 10 },{ "namezz": "Book", "price": 5 },{ "namezz": "Phone", "price": 500 },{ "namezz": "Computer", "price": 1000 },{ "namezz": "Keyboard", "price": 25 }]}
let final = obj.items.map(({ price, namezz }) => ({ namezz, data: [price] }))
console.log(final)

Related

Find every possibilitie in an array of object comparing key values

I have an specific math formula which receives three parameters and I'm trying to get from an array of object all the possibilities to run this math formula.
It's regards to sports.
Imagine a match where there are 3 possibility: Team A (win) - Team B (win) - Draw.
3 bet websites are dealing with this event. But the 3 of them have different odds values for this match.
I want to run those 3 bet websites to get all posibilities I can have for this event. Never getting more than one odd from the same bet website.
Example:
Website A: team A (win)
Website B: team B (win)
Website C: draw
I'm using JavaScript for that.
Thank you in advance for you time and support.
Really appreciate that.
Here is an example of data I have to get these possibilities.
Each obj is a website and into the object, the odds are on the key "outcomes".
The array of object here has 3 objects, but it can have more
[
{
"key": "betmgm",
"title": "BetMGM",
"last_update": "2022-12-14T04:30:40Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 138
},
{
"name": "Tottenham Hotspur",
"price": 200
},
{
"name": "Draw",
"price": 225
}
]
}
]
},
{
"key": "barstool",
"title": "Barstool Sportsbook",
"last_update": "2022-12-14T04:30:22Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 130
},
{
"name": "Tottenham Hotspur",
"price": 220
},
{
"name": "Draw",
"price": 230
}
]
}
]
},
{
"key": "twinspires",
"title": "TwinSpires",
"last_update": "2022-12-14T04:17:45Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 130
},
{
"name": "Tottenham Hotspur",
"price": 220
},
{
"name": "Draw",
"price": 230
}
]
}
]
}
]
I would like to receive an array with the possibilities like this:
[
{
"bookMaker": "TwinSpires",
"name": "Tottenham Hotspur",
"price": 230,
},
{
"bookMaker": "Barstool Sportsbook",
"name": "AC Milan",
"price": 130,
},
{
"bookMaker": "BetMGM",
"name": "Draw",
"price": 225,
}
]
The algorithm is quite simple. First, we take all the outcomes of the first Bet website. We shuffle them randomly.
Then we simply loop through the JSON object, which is a list of bet websites, not to mention the fact that both the number of outcomes must be the same as the number of bet websites. We assign for each bet website the next item of the shuffled outcomes. We log it to the console.
Here is the algorithm:
var data = [
{
"key": "betmgm",
"title": "BetMGM",
"last_update": "2022-12-14T04:30:40Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 138
},
{
"name": "Tottenham Hotspur",
"price": 200
},
{
"name": "Draw",
"price": 225
}
]
}
]
},
{
"key": "barstool",
"title": "Barstool Sportsbook",
"last_update": "2022-12-14T04:30:22Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 130
},
{
"name": "Tottenham Hotspur",
"price": 220
},
{
"name": "Draw",
"price": 230
}
]
}
]
},
{
"key": "twinspires",
"title": "TwinSpires",
"last_update": "2022-12-14T04:17:45Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 130
},
{
"name": "Tottenham Hotspur",
"price": 220
},
{
"name": "Draw",
"price": 230
}
]
}
]
}
];
start(data);
function start(data) {
var outcomes = data[0].markets[0].outcomes;
if (data.length != outcomes.length) {
alert("Invalid data!");
return;
}
var results = createResults(data);
printResults(results);
}
function createResults(data) {
var outcomes = data[0].markets[0].outcomes;
var newOutcomesNames = shuffleOutcomes(outcomes);
var results = [];
for (var i = 0; i < data.length; i++) {
var currentBetWebsite = data[i];
var currentResult = {};
var currentOutcomes = currentBetWebsite.markets[0].outcomes;
currentResult.bookMaker = currentBetWebsite.title;
currentResult.name = newOutcomesNames[i];
for (var j = 0; j < newOutcomesNames.length; j++) {
if (newOutcomesNames[i] == currentOutcomes[j].name) {
currentResult.price = currentOutcomes[j].price;
}
}
results.push(currentResult);
}
return results;
}
function printResults(results) {
console.log(results);
}
function shuffleOutcomes(outcomes) {
var parsedOutcomes = parseOutcomesNames(outcomes);
var outcomesLength = parsedOutcomes.length;
var newOutcomes = [];
for (var i = 0; i < outcomesLength; i++) {
var random = Math.floor(Math.random() * (outcomesLength - i));
newOutcomes.push(parsedOutcomes[random]);
parsedOutcomes.splice(random, 1);
}
return newOutcomes;
}
function parseOutcomesNames(outcomes) {
var outcomesNames = outcomes.map(o => o.name);
return outcomesNames;
}
Let me know, if you need any further assistance.

node.js find attributes with same value in multiple JSON files

Hey I would like to ask if it is possible to find lets say in 10 JSON files which are looking like this:
1.json:
{
"name": "Miami",
"attributes": [
{
"att_type": "People",
"value": "1000"
},
{
"att_type": "Cars",
"value": 300
}
]
}
2.json:
{
"name": "New York",
"attributes": [
{
"att_type": "People",
"value": "5000"
},
{
"att_type": "Cars",
"value": 900
}
]
}
And so on... just different attribute values.
Lets say I want to find only towns with People > 2500 and I'm not even sure if it is possible or do I need to upload the json files to some database perhaps?
Thank you.
const data = [{
"name": "Miami",
"attributes": [{
"att_type": "People",
"value": "1000"
},
{
"att_type": "Cars",
"value": 300
}
]
},
{
"name": "New York",
"attributes": [{
"att_type": "People",
"value": "5000"
},
{
"att_type": "Cars",
"value": 900
}
]
}
]
const result = data
// find cities with attribute `People` with value greater than 2500
.filter(d => +d.attributes.find(attr => attr.att_type === 'People').value > 2500)
// get name of the city
.map(d => d.name)
console.log(result)

Aggregate an object in which the value for each key is an array of objects

I'm using Underscore and Lodash to group an array by date. So far it's all working nicely and i'm getting an object in which the value for each key is an array of objects, like this:
{
"april": [
{
"quantity": "200",
"date": "05/04/2020, 23:43",
"price": "150",
"product": "Washing Machine",
"provider": "LG",
"total": 30000
},
{
"quantity": "1000",
"date": "10/04/2020, 00:35",
"price": "800",
"product": "Television",
"provider": "Samsung",
"total": 800000
},
{
"quantity": "3000",
"date": "10/04/2020, 18:02",
"price": "2",
"product": "Computer",
"provider": "Sony",
"total": 600000
},
{
"quantity": "1000",
"date": "10/04/2020, 18:03",
"price": "300",
"product": "Bluetooth Speaker",
"provider": "Sony",
"total": 300000
}
],
"march": [
{
"quantity": "400",
"date": "18/03/2020, 23:47",
"price": "230",
"product": "Home Theatre",
"provider": "Bose",
"total": 92000
}
],
"february": [
{
"quantity": "550",
"date": "07/02/2020, 23:52",
"price": "300",
"product": "Printer",
"provider": "Epson",
"total": 165000
},
{
"quantity": "750",
"date": "07/02/2020, 23:52",
"price": "200",
"product": "Television",
"provider": "Panasonic",
"total": 150000
}
]
}
I want to know who is the biggest provider by total for each month (for example for April is Sony with two different purchases totalling $900,000), but i've been stuck trying to access and aggregate the data. I know there are tons of similar questions here in Stackoverflow, but surprisingly I haven't been able to find any similar question with this kind of data structure.
Any help would be highly appreciated.
You could combine map() and reduce() to achieve what you're looking for, something like:
let data = {
april: [{
quantity: "200",
date: "05/04/2020, 23:43",
price: "150",
product: "Washing Machine",
provider: "LG",
total: 30000,
},
{
quantity: "1000",
date: "10/04/2020, 00:35",
price: "800",
product: "Television",
provider: "Samsung",
total: 800000,
},
{
quantity: "3000",
date: "10/04/2020, 18:02",
price: "2",
product: "Computer",
provider: "Sony",
total: 600000,
},
{
quantity: "1000",
date: "10/04/2020, 18:03",
price: "300",
product: "Bluetooth Speaker",
provider: "Sony",
total: 300000,
},
],
march: [{
quantity: "400",
date: "18/03/2020, 23:47",
price: "230",
product: "Home Theatre",
provider: "Bose",
total: 92000,
}, ],
february: [{
quantity: "550",
date: "07/02/2020, 23:52",
price: "300",
product: "Printer",
provider: "Epson",
total: 165000,
},
{
quantity: "750",
date: "07/02/2020, 23:52",
price: "200",
product: "Television",
provider: "Panasonic",
total: 150000,
},
],
};
let aggregatedData = Object.keys(data).map((month) =>
data[month].reduce((acc, current, i) => {
let existing = acc.find((o) => o.provider === current.provider);
if (existing) {
existing.total += current.total;
} else {
acc[i] = { provider: current.provider, total: current.total };
}
return acc;
}, [])
);
let biggestProviders = aggregatedData.map((data) =>
data.reduce((p, c) => (c.total > p.total ? c : p))
);
console.log(biggestProviders);
console.log(biggestProviders.map(o => o.provider));
Based on the keys of the data, we get each month's array of company data and reduce the objects, accumulating their totals if the provider already exists. Then we map and reduce the resulting data by comparing which one had the highest total, then we just map the final result to get the name of the provider.
Edge case: I've also noticed a small issue with this approach, which is in the case of there being two providers with exactly the same total, so I've made a quick snippet that will just return an array of arrays of providers that just so happen to have the same total. If we don't take that into consideration we might be returning just one of the biggest providers by total:
let data = {
april: [{
quantity: "200",
date: "05/04/2020, 23:43",
price: "150",
product: "Washing Machine",
provider: "LG",
total: 30000,
},
{
quantity: "1000",
date: "10/04/2020, 00:35",
price: "800",
product: "Television",
provider: "Samsung",
total: 900000,
},
{
quantity: "3000",
date: "10/04/2020, 18:02",
price: "2",
product: "Computer",
provider: "Sony",
total: 600000,
},
{
quantity: "1000",
date: "10/04/2020, 18:03",
price: "300",
product: "Bluetooth Speaker",
provider: "Sony",
total: 300000,
},
],
march: [{
quantity: "400",
date: "18/03/2020, 23:47",
price: "230",
product: "Home Theatre",
provider: "Bose",
total: 92000,
}, ],
february: [{
quantity: "550",
date: "07/02/2020, 23:52",
price: "300",
product: "Printer",
provider: "Epson",
total: 165000,
},
{
quantity: "750",
date: "07/02/2020, 23:52",
price: "200",
product: "Television",
provider: "Panasonic",
total: 165000,
},
],
};
let aggregatedData = Object.keys(data).map((month) =>
data[month].reduce((acc, current, i) => {
let existing = acc.find((o) => o.provider === current.provider);
if (existing) {
existing.total += current.total;
} else {
acc[i] = {
provider: current.provider,
total: current.total
};
}
return acc;
}, [])
);
let biggestProviders = aggregatedData.map((data) =>
data.reduce((p, c) => {
if (p.length === 0) return p.concat(c);
if (c.total === p[0].total) {
p.push(c);
} else {
p = c.total > p[0].total ? Array.of(c) : Array.of(...p);
}
return p;
}, [])
);
console.log(biggestProviders);
You can use a temporary object (resultObj below) to accumulate the total for each provider per month as you iterate through the list.
Sample of an object for keeping track of max total price per month:
var resultObj = {
"max" : {
"num" : 0, // current max total goes here
"provider" : "" // provider with max total goes here
},
"maxObject" : {}, // max items for each month stored here
getMax : function() {
// returns current max object to be added to maxObject[month]
return { "provider": this.max.provider, "total": this.max.num };
},
"reset" : function() { // reset max
this.max.num = 0;
this.max.provider = ""
},
"createKey" : function(month) { // create month key
if(!this.hasOwnProperty(month))
this[month] = {};
}
};
And the function to iterate through the array of objects:
function getMaxValue() {
for(let month in obj) { // for each month in the object
resultObj.reset(); // reset max
resultObj.createKey(month); // create key for month in resultObj
obj[month].forEach(function(el) { // for each object within month
if(resultObj[month][el.provider]) { // if the provider exists as a key
resultObj[month][el.provider] += el.total;
} else { // provider doesn't yet exist
resultObj[month][el.provider] = el.total;
}
// if current total is greater than current max (for given month)
if(resultObj[month][el.provider] > resultObj.max.num) {
resultObj.max.num = resultObj[month][el.provider];
resultObj.max.provider = el.provider;
}
});
resultObj.maxObject[month] = resultObj.getMax(); // generate result for month
}
return resultObj.maxObject; // return the result object
}
Check and test below:
var obj = {
"april": [
{
"quantity": "200",
"date": "05/04/2020, 23:43",
"price": "150",
"product": "Washing Machine",
"provider": "LG",
"total": 30000
},
{
"quantity": "1000",
"date": "10/04/2020, 00:35",
"price": "800",
"product": "Television",
"provider": "Samsung",
"total": 800000
},
{
"quantity": "3000",
"date": "10/04/2020, 18:02",
"price": "2",
"product": "Computer",
"provider": "Sony",
"total": 600000
},
{
"quantity": "1000",
"date": "10/04/2020, 18:03",
"price": "300",
"product": "Bluetooth Speaker",
"provider": "Sony",
"total": 300000
}
],
"march": [
{
"quantity": "400",
"date": "18/03/2020, 23:47",
"price": "230",
"product": "Home Theatre",
"provider": "Bose",
"total": 92000
}
],
"february": [
{
"quantity": "550",
"date": "07/02/2020, 23:52",
"price": "300",
"product": "Printer",
"provider": "Epson",
"total": 165000
},
{
"quantity": "750",
"date": "07/02/2020, 23:52",
"price": "200",
"product": "Television",
"provider": "Panasonic",
"total": 150000
}
]
};
var resultObj = {
"max" : {
"num" : 0,
"provider" : ""
},
"maxObject" : {},
"getMax" : function() {
return { "provider": this.max.provider, "total": this.max.num };
},
"reset" : function() {
this.max.num = 0;
this.max.provider = "";
},
"createKey" : function(month) {
if(!this.hasOwnProperty(month))
this[month] = {};
}
};
function getMaxValue() {
for(let month in obj) {
resultObj.reset();
resultObj.createKey(month);
obj[month].forEach(function(el) {
if(resultObj[month][el.provider]) {
resultObj[month][el.provider] += el.total;
} else {
resultObj[month][el.provider] = el.total;
}
if(resultObj[month][el.provider] > resultObj.max.num) {
resultObj.max.num = resultObj[month][el.provider];
resultObj.max.provider = el.provider;
}
});
resultObj.maxObject[month] = resultObj.getMax();
}
return resultObj.maxObject;
}
var maxValues = getMaxValue(); // receives an object
console.log( maxValues ); // prints the all the results
console.log("\nmax for April:");
console.log( maxValues.april ); // prints results for April
console.log("\nNow to check resultObj:");
console.log( resultObj ); // prints the whole temp object

How to groupBy an attribute inside the second array with javascript

I am trying to convert an array object to a new set of arrays grouped by their value. In this case, it is the date value.
What I have tried in in the below code, but I didn't get the results of what I wanted. Can you please help me find the right solution for this problem?
INPUT
let array = [
{
"category": {
"code": "1558950145861"},
"lines": [
{
"date": "2020-02-26",
"price": 9260,
"dispo": 5
},
{
"date": "2020-02-29",
"price": 6300,
"dispo": 9
},
{
"date": "2020-04-01",
"price": 7700,
"dispo": 23
}
]
},
{
"category": {
"code": "1788858954441"
},
"lines": [
{
"date": "2020-02-26",
"price": 6260,
"dispo": 2
},
{
"date": "2020-02-29",
"price": 5500,
"dispo": 4
},
{
"date": "2020-04-01",
"price": 840,
"dispo": 7
}
]
}
];
Desired OUTPUT
[{
"date": "2020-02-26",
"lines": [{
"price": 9260,
"dispo": 5
}, {
"price": 6260,
"dispo": 2
}]
}, {
"date": "2020-02-29",
"lines": [{
"price": 6300,
"dispo": 9
}, {
"price": 5500,
"dispo": 4
}]
}, {
"date": "2020-04-01",
"lines": [{
"price": 7700,
"dispo": 23
}, {
"price": 840,
"dispo": 7
}]
}]
code that I wrote
var result = (_array)
.groupBy(x => {
for (let j = 0; j < x.lines.length; j += 1) {
return x.lines[j].date;
}
})
.map((value, key) => ({
date: key,
lines: value
})).value();
I want my code to generate the desired output, but it isn't doing that. What might I be doing wrong?
try this
let array = [{ "category": { "code": "1558950145861" }, "lines": [{ "date": "2020-02-26", "price": 9260, "dispo": 5 }, { "date": "2020-02-29", "price": 6300, "dispo": 9 }, { "date": "2020-04-01", "price": 7700, "dispo": 23 }] }, { "category": { "code": "1788858954441" }, "lines": [{ "date": "2020-02-26", "price": 6260, "dispo": 2 }, { "date": "2020-02-29", "price": 5500, "dispo": 4 }, { "date": "2020-04-01", "price": 840, "dispo": 7 }] }]
const groupBy = (arr) => arr.reduce((acc, ele)=>( (acc[ele.date] = acc[ele.date] || []).push(ele), acc),{})
const all = [].concat(...array.map(ele=> ele.lines))
const format = ele => ele.map(({price, dispo})=>({price, dispo}))
console.log(Object.entries(groupBy(all)).map(([date, lines])=> ({date, lines: format(lines)})))
Try something like this :
var out = {}
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array[i]["lines"].length; j++) {
let e = array[i]["lines"][j];
if (!out[e["date"]]) {
out[e["date"]] = [];
}
out[e["date"]].push({"price": e["price"], "dispo": e["dispo"]});
}
}
var result = [];
for (let k in out) {
result.push({"date": k, "lines": out[k]});
}
The result variable has the desired output format.
You don't appear to need the category value, so first I'd merge the lines into a single array where you can groupBy from there:
// using your input called 'array'
// First collect just the line arrays:
var arrayOfLineArrays=array.map(category => category.lines);
// Merge them into one bigger array:
var allLines = _.flatten(arrayOfLineArrays);
// Now you can groupBy with ease:
var dateGroupsObject = _(allLines).groupBy(line => line.date);
// And map to an array:
var result = _.values(_.mapObject(dateGroupsObject, (value, key) => ({
date: key,
lines: value
}))));

Create a Json structure from arrays by code - Typescript

I must create a Json object that represent a Sandwich configuration (bread, meat, sauces etc...) from different arrays that contains the ingredients for each category (1 array for bread, 1 for meat etc...) like this {name: 'x', price: 'y'}
The categories are defined but each array can have a different number of elements.
It's possible to obtain, starting from these arrays, something like that by code? I need this to make a recap of my sandwich in the cart page after the user choose all the ingredients. (each cat_1 it's a type of ingredient).
sandwich{
"cat_1": {[
{
"name": "x",
"price": "x"
}
]
},
"cat_2": {[
{
"name": "x",
"price": "x"
}
]
},
"cat_3": {[
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
}
]
},
"cat_4": {[
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
}
]
},
"cat_5": {[
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
}
]
}
}
I don't post any code beacuse I don't know what can help.
Actually, I push all my arrays into a big array and I have something like that, but it's a lot different from what I want achieve.
[{
"name": "Montanaro",
"price": "5.00"
}, {
"name": "Manzo",
"price": "5.00"
}, {
"name": "Fossa",
"price": "1.00"
}, {
"name": "Caciotta",
"price": "1.00"
}, {
"name": "Guacamole",
"price": "0.50"
}, {
"name": "Olive ascolane",
"price": "1.00"
}, {
"name": "Mozzarelline fritte",
"price": "0.50"
}, {
"name": "Onion Rings",
"price": "1.00"
}]
I'm not a json expert so I don't know where to start...
Thank you to everyone that could help me.
Have a good day
Have you tried to split the ingredients and add an element from the list for each sandwich?
let breads = [{name: "bread1", price: 1.00}, {name: "bread2", price: 2.00}, {name: "bread3", price: 3.00}];
let meats = [{name: "meat1" , price: 1.00}, {name: "meat2" , price: 2.00}, {name: "meat3" , price: 3.00}];
let sauces = [{name: "sauce1", price: 1.00}, {name: "sauce2", price: 2.00}, {name: "sauce3", price: 3.00}];
let s1 = {
bread : breads[Math.floor(Math.random()*breads.length)],
meats : meats[Math.floor(Math.random()*meats.length)],
sauces : sauces[Math.floor(Math.random()*sauces.length)]
}
let sandwich = {s1};
console.log(sandwich);
Here is an example: https://codepen.io/WildLlama/pen/VVLYmL?editors=0011

Categories

Resources