Javascript create array of objects dynamically - javascript

I have a JSON response i.e.
[{"name":"title","value":"STEP-01","translation":"STEP-01"},{"name":"meta_description","value":"","translation":"meta desc"}, ......]
from this I want to create an array of objects dynamically so that I get name as key and translation as value
like
data.en = {
title : 'STEP-01',
meta-description : meta desc
}
I have tried this but it creates an array
jsonObj = []
$.each(result, function (index, value) {
lang_array = {};
lang_array[value.name] = value.translation;
jsonObj.push(lang_array);
})

According to your example you are trying to create a JS object, and not an array.
Option 1: Use Array#reduce to collect the name and translation of each object to a new object:
const data = [{"name":"title","value":"STEP-01","translation":"STEP-01"},{"name":"meta_description","value":"","translation":"meta desc"}];
const result = data.reduce((r, { name, translation }) => {
r[name] = translation;
return r;
}, {});
console.log(result);
Option 2: Use a Array#map to create a collection of objects with the properties and the values, and combine them to a single object using Object#assign and spread:
const data = [{"name":"title","value":"STEP-01","translation":"STEP-01"},{"name":"meta_description","value":"","translation":"meta desc"}];
const result = Object.assign(...data.map(({ name, translation }) => ({ [name]: translation })));
console.log(result);

Related

How to convert json object keys into different arrays removing the duplicate

I'm having the JSON like this i need to group this JSON with all the keys in JSON object and value should in array (excluding duplicates).
var people = [
{sex:"Male", name:"Jeff"},
{sex:"Female", name:"Megan"},
{sex:"Male", name:"Taylor"},
{sex:"Female", name:"Madison"}
];
My output should be like
{"sex":["Male","Female"],"name":["Jeff","Megan","Taylor","Madison"]}
how we can able to achieve this
function getValues(array) {
var result = {};
array.forEach(obj => {
Object.keys(obj).forEach(key => {
if(!Array.isArray(result[key]))
result[key] = [];
result[key].push(obj[key]);
})
})
return result;
}
You could use the Array.reduce() method to transform your array into a single object:
var people = [
{sex:"Male", name:"Jeff"},
{sex:"Female", name:"Megan"},
{sex:"Male", name:"Taylor"},
{sex:"Female", name:"Madison"}
];
const transformed = people.reduce((acc, e) => {
Object.keys(e).forEach((k) => {
if (!acc[k]) acc[k] = [];
if (!acc[k].includes(e[k])) acc[k].push(e[k]);
});
return acc;
}, {});
console.log(transformed);
If for one of the object keys (sex or name in this case) a value array does not exist, it is created. Before a value is pushed into any of the value arrays, it is verified that it is not already present in that array.

Filter JSON by key value with JavaScript

given an array of objects in users.json:
{"key":"userSubscriptions","value":
[{"channel":"Netflix","user":"Bobby","region":"NA"},
[{"channel":"Netflix","user":"Bobby","region":"EU"},
[{"channel":"Netflix","user":"Jamie","region":"SEA"},
[{"channel":"Prime Video","user":"Bobby","region":"NA"}]}
How would one filter such that the end result will be
console.log(result); // Bobby, your region subscriptions are: Netflix: (NA, EU), Prime Video: (NA)
Thank you!
EDIT: i tried using .filter() & .map() method but no luck so far
you have to use lodash to group data, then map data
var data = {
"key":"userSubscriptions",
"value":
[{"channel":"Netflix","user":"Bobby","region":"NA"},
{"channel":"Netflix","user":"Bobby","region":"EU"},
{"channel":"Netflix","user":"Jamie","region":"SEA"},
{"channel":"Prime Video","user":"Bobby","region":"NA"}]
}
var users = _.chain(data.value)
.groupBy("user").map((value, key) => ({ user: key, data: value })).value();
users.forEach(element => {
console.log(element)
console.log(`${element.user}, your region subscriptions are: Netflix: ${element.data.map(c=>c.channel).join(',')}, Prime Video: ${element.data.map(c=>c.region).join(',')}`)
});
Your JSON data is invalid. However, I think I adapted it to what you intended.
This breaks the data down into a by-user format, and supplies a function to output the Subscriptions and Regions for any named user.
const jsonString = `{"key":"userSubscriptions","value":[{"channel":"Netflix","user":"Bobby","region":"NA"},{"channel":"Netflix","user":"Bobby","region":"EU"},{"channel":"Netflix","user":"Jamie","region":"SEA"},{"channel":"Prime Video","user":"Bobby","region":"NA"}]}`;
const obj = JSON.parse(jsonString);                                  // parse the data from a string into an object
const byUser = obj.value.reduce((acc, o) => {                        // reduce the "value" array to a single object
if (!acc[o.user]) acc[o.user] = {};                                // create acc.userName if it does not exist
if (acc[o.user][o.channel]) acc[o.user][o.channel].push(o.region); // if acc.userName.channelName has an array, add this region to it
else acc[o.user][o.channel] = [o.region];                          // else create an array with this region in it
return acc;                                                        // keep the created object for the next iteration
}, {});
function printForUser(userName) {                                    // create a function that takes a user's name
const user = byUser[userName];                                     // take the user object from the byUser object
return Object.keys(user).reduce((acc, k) => {                      // reduce the keys of the user object to one string
return acc + ` ${k}: (${user[k].join(", ")}),`;                  // add on each subscription and regions
}, `${userName}, your region subscriptions are:`).slice(0, -1);    // initialize the string and remove the last comma
}
console.log( printForUser("Bobby") );

Merge object Ramda

I am trying to perform um compare merge com ramda of the following values:
const data1 = {"crypto1":"BTCUSDT","crypto2":"ADABTC","crypto3":"ETHUPUSDT"};
const data2 = [
{"symbol":"ETHBTC","baseAsset":"ETH","status":"TRADING","id":1},
{"symbol":"BTCUSDT","baseAsset":"LTC","status":"TRADING","id":2},
{"symbol":"ETHUPUSDT","baseAsset":"BNB","status":"TRADING","id":3},
{"symbol":"NEOBTC","baseAsset":"NEO","status":"TRADING","id":4},
{"symbol":"ADABTC","baseAsset":"QTUM","status":"TRADING","id":5},
{"symbol":"EOSETH","baseAsset":"EOS","status":"TRADING","id":6}
];
What I need is to do a search for data1 (crypto) and match with data2, the expected result is:
result = [
{"symbol":"BTCUSDT","baseAsset":"LTC","status":"TRADING","id":1},
{"symbol":"ADABTC","baseAsset":"QTUM","status":"TRADING","id":2},
{"symbol":"ETHUPUSDT","baseAsset":"BNB","status":"TRADING","id":3}
]
It should be noted that the id must change according to the order of the data in the data1 variable
Thanking the support with some recommendation on how I should do it.
Use R.indexBy to create a dictionary of { [symbol]: object }, and then pick the items from the dictionary using R.props, after converting the keys (data1) to an array using R.values:
const { curry, pipe, indexBy, prop, props, values } = R;
const fn = curry((keys, data) => pipe(
indexBy(prop('symbol')), // index the values by the symbol
props(values(keys)) // convert the keys to an array and get them from the dictionary
)(data));
const data1 = {"crypto1":"BTCUSDT","crypto2":"ADABTC","crypto3":"ETHUPUSDT"};
const data2 = [{"symbol":"ETHBTC","baseAsset":"ETH","status":"TRADING","id":1},{"symbol":"BTCUSDT","baseAsset":"LTC","status":"TRADING","id":2},{"symbol":"ETHUPUSDT","baseAsset":"BNB","status":"TRADING","id":3},{"symbol":"NEOBTC","baseAsset":"NEO","status":"TRADING","id":4},{"symbol":"ADABTC","baseAsset":"QTUM","status":"TRADING","id":5},{"symbol":"EOSETH","baseAsset":"EOS","status":"TRADING","id":6}];
const result = fn(data1, data2);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
A very simple approach would be to :
map over the values from data1 - use R.values
find the object containing that as value against 'symbol' from 'data2' - use R.find and R.propEq
add indices accordingly - use R.addIndex
const R = require('ramda');
const result = R.addIndex(R.map)((k, idx) => ({
...R.find(R.propEq('symbol', k))(data2),
id: idx+1
}))(R.values(data1));
console.log(result);

Destruct a string from split to named object

I am investigating how create a named object in one go, using destruct
A search for javascript destruct* split object did not reveal how to directly destruct a string into an object using split.
I do not mean reduce or map but pure destructing
const list = { ..... } = `......`.split(..)
or at least
const rowItem = { ..... } = `......`.split(..)
My initial version works, but there should be a neater way with less steps
The initial split on lines is fine. It is the filling of the list using destruct I am curious about
const rows = `100|Description 1|a|
101|Description 2|a|
102|Description 3|b|`.split("\n")
let list = {}
rows.forEach(row => {
const [ProductId, Description, subCat, ] = row.split("|")
list[ProductId] = {"Description": Description, "subCat": subCat }
})
console.log(list)
You can do something like this with IIFE
const rows = `100|Description 1|a|
101|Description 2|a|
102|Description 3|b|`.split("\n")
let list = {}
rows.forEach(row => {
(([ProductId, Description, subCat]) => (list[ProductId] = {
Description,
subCat
}))(row.split("|"))
})
console.log(list)
You can consider using Object.fromEntries if it's available in your environment
const rows = Object.fromEntries(`100|Description 1|a|
101|Description 2|a|
102|Description 3|b|`
.split("\n")
.map(row => row.split('|'))
.map(([key, Description, subCat]) => [key, { Description, subCat }])
);
console.log(rows);
It is possible to set the property to an existing object while destructuring.
const row = { Description: 'Description 1', subCat: 'a' },
o = { }; // existing object to be updated;
({ Description: o.Description, subCat: o.subCat } = row);
console.log(o)
In your case, you have dynamic id keys, nested property updates and you are destructuring an array instead of an object. It becomes complex, but it is possible to apply the above logic to your code (This is extremely hackish and purely academic. This should never ever be used in an actual code base)
const str = "100|Description 1|a|",
splits = str.split('|'),
list = {};// existing object
({ 0: id, [-1]: list[id]= {}, 1: list[id].Description, 2: list[id].subCat } = splits)
console.log(list)
This destructures the array like an object. It gets the property with key 0 and sets it to the id variable. Then destructure the -1 property. This is non-existent, so the default value is used and list[id] = {} is set.
This is how the transpiled code looks like:
var _str$split = str.split('|');
id = _str$split[0];
list[id] = _str$split[-1] === undefined ? {} : _str$split[-1];
list[id].Description = _str$split[1];
list[id].subCat = _str$split[2];
console.log(list);
Applying this to your original snippet:
const rows = `100|Description 1|a|
101|Description 2|a|
102|Description 3|b|`
let list = {},
id;
rows.split("\n")
.forEach(str => ({
0: id,
[-1]: list[id] = {},
1: list[id].Description,
2: list[id].subCat
} = str.split('|'))
)
console.log(list)
Another option is to use matchAll and Object.fromEntries()
const str = `100|Description 1|a|
101|Description 2|a|
102|Description 3|b|`;
const regex = /(\d+)\|([^|]+)\|(\w+)/g;
const output = Object.fromEntries(
Array.from(
str.matchAll(regex), ([, id, Description, subCat]) => [id, { Description, subCat }]
)
)
console.log(output)
matchAll is still in Draft stage but it is implemented except by IE and Safari. You can easily polyfill it. It is basically looping through exec results

How to convert the related model data to Array while getting parent model data from real database?

I have a schema in realm db where data comes from different models to parent model.
I am able to convert the data I get from parent model to Array by doing
static get() {
let result = realm.objects(this.schema.name)
return result.map(x => Object.assign({}, x))
}
Here is sample the data inside parent model,
[
{"deal_id":"d001","product_id":"p001",
"user_defined_attributes":{"0":{"name":"Color","value":"Red"},"1":{"name":"Quality","value":"NO.1"}},
"deal_channels":{"0":{"channel_id":"d001_u00001_u00002","to_user_id":"u00002","deal_id":"d001",
"chat_messages":{"0":{"message_id":"m1","channel_id":"d001_u00001_u00002","time_stamp":1533548036,"sendor_id":"u00001","storage_status":"active","status":"seen"}}}}
]
How can I convert the data in 'user_defined_attributes', 'deal_channels' and then data in 'chat_messages' to Array.
You can convert the given JSON object using below code.
var obj = obj[0];
var convert = (o) => Object.keys(o).map(k => o[k]);
obj.user_defined_attributes = convert(obj.user_defined_attributes)
obj.deal_channels = convert(obj.deal_channels).map(d => {
d.chat_messages = convert(d.chat_messages);
return d;
});

Categories

Resources