Transform nested array of objects to an object - javascript

I am trying to convert a nested array to an object, I made several attempts but without success.
these are the data i have
[
['key1', { childKey1: "text" }, { childKey2: "text" }],
['key2', { childKey1: "text" }, { childKey2: "text" }]
]
this is the data i need
{
key1: {
childKey1: "text",
childKey2: "text"
},
key2: {
childKey1: "text",
childKey2: "text"
}
}

Map the data to entries - [[key, value], [key, value]]. Use destructuring to get the key (the 1st item in a sub-array), and rest syntax to get an array of objects. Merge the array of objects by spreading the array of objects into Object.assign() to get the value. Use Object.fromEntries() to convert the entries to an object.
const data = [['key1', {childKey1: "text"}, {childKey2: "text"}], ['key2', {childKey1: "text"}, {childKey2: "text"}]]
const result = Object.fromEntries(data.map(
([k, ...v]) => [k, Object.assign({}, ...v)]
))
console.log(result)

You may try reduce to achieve such task. You could do something like this:
const data = [
["key1", { childKey1: "text" }, { childKey2: "text" }],
["key2", { childKey1: "text" }, { childKey2: "text" }]
];
function dataToJSON(data) {
return data.reduce((acc, current) => {
const [key, ...values] = current;
acc[key] = Object.assign({}, ...values);
return acc;
}, {});
}
console.log(dataToJSON(data));
Works perfect for any number of children. You have to be careful with repeated keys not to overwrite a previous one.

.reduce() method is another way to approach this.
const arr = [['key1', {childKey1: "text"}, {childKey2: "text"}], ['key2', {childKey1: "text"}, {childKey2: "text"}]];
const newArr = arr.reduce((accumulator, currVal) => {
const [key, ...values] = currVal; // destruct array and separate key from all other values
accumulator[key] = Object.assign({}, ...values); // assign values to your final object, using the key extracted above
return accumulator;
}, {});
console.log(newArr);

I know this was already answered, but here's my attempt at it:
let jsonArray = [['key1', {childKey1: "text"}, {childKey2: "text"}], ['key2', {childKey1: "text"}, {childKey2: "text"}]];
let newJson = {};
for(var i=0; i<jsonArray.length; i++){
newJson[jsonArray[i][0]] = Object.assign({}, ...jsonArray[i].slice(1));
}
console.log(newJson);

Related

How to convert an array with one object and multiple keys into an array of multiple objects using those keys and their values?

I have an array like so with a single object inside:
FirstArray = [{
"category": "None",
"ARFE": 553.5,
"BV": 900,
"RF rfeer": 0,
.....
}]
I want to convert it so that every key-value pair (where the value is a number) in the object is in its own object like the following:
NewArray = [{
name: "ARFE",
value: 553.05
}, {
name: "BV",
value: 900
}, {
name: "RF rfeer",
value: 0
}, .....]
Here, each key was assigned a new key called name, and the value for the original key was assigned a new key called value. Those pairs are then put into their own object inside the array.
Note that "category": "None" is not its own object in the array since "None" is non-numerical.
It's also important to note that there could be many key-value pairs, so it's not just limited to the items above (e.g., "ARFE": 553.5, etc.)
What I have so far:
I know you can separate a single object into multiple objects:
NewArray = Object.entries(FirstArray).reduce((prev, [og, nw]) => {
let [name, value] = og.match(/\D+|\d+$/g)
prev[value] = { ...(prev[value] || {}), [name]: nw }
return prev;
}, {})
I also know how that you can create a new object with new keys like so:
NewArray = Object.assign(
...Object.entries(FirstArray).map(([key, value]) => ({ [key]: name }))
);
However, I'm having trouble putting everything together. How would I be able to achieve NewArray from FirstArray?
You were pretty close. All you needed to do is specify the name:
const data = {
"category": "None",
"ARFE": 553.5,
"BV": 900,
"RF rfeer": 0
};
const result = Object
.entries(data)
.filter(([_, value]) => typeof value === 'number')
.map(([key, value]) => ({ name: key, value }));
console.log(result);
Also, if you don't want { "name": "category", "value": "None" } to be included in the result, you can just filter it:
const result = Object
.entries(data)
.filter(([ key ]) => key !== 'category')
.map(([key, value]) => ({ name: key, value }));
Object.entries on array has no sense at all, use it on the object
const FirstArray = [{
"category": "None",
"ARFE": 553.5,
"BV": 900,
"RF rfeer": 0,
}]
const newObject = Object.entries(FirstArray[0]).reduce((array, [key, value]) => {
return [...array, {
name: key,
value
}]
}, [])
console.log(newObject)
reduce is not the right way to go. Simply use map:
Object.entries(FirstArray[0])
.filter(x => !isNaN(x[1])) // filter out non-numeric values
.map(([name, value]) => ({name, value}))

Convert array object into object in Javascript

I am trying to covert an array object into object array with matching filterKey and filterValue of current object.
[
{
"filterKey": "name",
"filterValue": [
{
"value": "abc"
},
{
"value": "def"
}
]
},
{
"filterKey": "status",
"filterValue": [
{
"value": "active"
},
{
"value": "pending"
}
]
}
]
The result I am expecting as below:
{
"name": [
"abc",
"def"
],
"statuses": [
"active",
"pending"
]
}
I tried
obj.map(item => Object.values(item.filterValue))
reduce over the array of data, and create a new object, using map to create a new array of values for each new property.
const data=[{filterKey:'name',filterValue:[{value:'abc'},{value:'def'}]},{filterKey:'status',filterValue:[{value:'active'},{value:'pending'}]}];
// Iterate over the array with `reduce`
const out = data.reduce((acc, obj) => {
// Extract the key and value from each object
const { filterKey: key, filterValue: value } = obj;
// Return the accumulator object updated with the new key
// and array of values gained from `map`
return {...acc, [key]: value.map(o => o.value)};
}, {});
console.log(out);
const oldArr = [{"filterKey": "name","filterValue": [{"value": "abc"},{"value": "def"}]},{"filterKey": "status","filterValue": [{"value": "active"},{"value": "pending"}]}];
const newObj = oldArr.reduce((a, b) => { // reduce to single object
const values = b.filterValue.map(x => x.value); // map the filter values to their strings
if (a[b.filterKey]) a[b.filterKey].concat(values); // if the key already exists add the strings to it (does not apply to your example)
else a[b.filterKey] = values; // else create a new entry with the strings
return a;
}, {});
// if you really want to rename status => statuses
newObj.statuses = newObj.status;
delete newObj.status;
console.log(newObj);

combining duplicate key's values in JavaScript array

I have an Array that contain some keys/values one of the values is an array I want combining the value of array from all recorded that have same key in my Array.
Below is an Simple Example to demonstrate, I am not able to construct its logic so seeking help in building a logic to it.
[{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}]
I want Result Like,
[{"somekey":["Some Value Pushed","Second Value"]}]
The reduce() function of Array Object in JavaScript can merge any array into a single Object.
I wrote a single-line code to solve this problem.
I updated result with the array.
const arr = [{
somekey: "Some Value Pushed",
},
{
somekey2: "Second Value2",
},
{
somekey: "Some Value Pushed",
},
{
somekey2: "Second Value3",
},
{
somekey3: "",
},
{},
];
const ansObj = arr.reduce(
(prv, cur) => {
Object.entries(cur).forEach(([key, v]) => key in prv ? prv[key].push(v) : (prv[key] = [v]));
return prv;
}, {}
)
const ansArray = Object.entries(ansObj).map(([key, value])=>({[key]:value}));
console.log(ansArray);
You can try something like this:
var array = [{
name: "foo1",
value: "val1"
}, {
name: "foo1",
value: ["val2", "val3"]
}, {
name: "foo2",
value: "val4"
}];
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.name === item.name;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].value = output[existingIndex].value.concat(item.value);
} else {
if (typeof item.value === 'string')
item.value = [item.value];
output.push(item);
}
});
Or, another option using Lodash
function mergeNames (arr) {
return _.chain(arr).groupBy('name').mapValues(function (v) {
return _.chain(v).pluck('value').flattenDeep();
}).value();
}
Maybe something like:
const data = [
{"somekey":"Some Value Pushed"},
{"somekey":"Second Value", "otherkey": 1},
{"otherkey": 2}
];
const merge_and_group = (obj1, obj2) =>
Object.entries(obj2).reduce(
(acc, [key, val]) => {
acc[key] ??= [];
acc[key].push(val);
return acc;
},
obj1
);
const res = data.reduce(merge_and_group, {});
console.log(res);
const arr = [{
"somekey": "Some Value Pushed"
}, {
"somekey2": "Second Value2"
}, {
"somekey": "Some Value Pushed"
}, {
"somekey2": "Second Value3"
}]
const newarr = {}
arr.forEach(obj => {
for (const [key, value] of Object.entries(obj)) {
if (newarr[key]) newarr[key].push(value)
else newarr[key] = [value]
}
})
console.log(newarr)
Array.prototype.reduce() is a possible option.
the reduce() method executes a reducer function which is provided as an input on each element of the array and returning a single output value.
const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}];
const res = array.reduce((acc, el) => {
const [key, value] = Object.entries(el)[0];
(acc[key] || (acc[key] = [])).push(value);
return acc;
}, {});
console.log(res)
Assuming each element of your array is an object with a single key.
const array = [
{ somekey: "Some Value Pushed" },
{ somekey: "Second Value" },
{ foo: "bar" },
{ foo: "baz" },
{ somekey: "Third Value" },
];
const result = [];
array.forEach(el => {
let [key, value] = Object.entries(el)[0];
for (let el of result) if (key in el) {
el[key].push(value);
return;
}
result.push({ [key]: [value] });
});
console.dir(result);
If your array has only "somekey" as keys then you can use map method as following:
const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}];
const valuesArray = array.map(obj => obj.somekey);
result = [{"somekey":valuesArray}];
console.log(result)
If your array has other keys along with "somekey" and you like to separate values corresponding to only "somekey" then try the following:
const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}, {"otherkey":"other Value"}];
const filteredArray = array.filter((obj) => {
return "somekey" in obj
}, []);
const valuesArray = filteredArray.map(obj => obj.somekey);
result = [{"somekey":valuesArray}];
console.log(result)

How to access KeyValuePair collection as JSON array

I'm making Ajax calls to a page in ASP.NET Core 3.1.
The response is a JsonResult whose Value property is an instance of a custom class, itself containing various string and collection properties.
One of these collections is a Dictionary<string, string>, which I can then access in JavaScript along the following lines:
var dictionary = response.DictionaryObj;
for (key in dictionary) {
DoSomeStuff(key, dictionary[key]);
}
However another of these collections requires a non-unique 'key', and is currently a List<KeyValuePair>
This ends up in JavaScript as an array of objects, which I can access like this:
var kvps = response.KvpList;
for (i = 0; i < kvps.length; i++) {
var kvp = kvps[i];
DoSomeMoreStuff(kvp.key, kvp.value);
}
The latter seems far less elegant - is there a way of packaging up the KeyValuePairs in a way that would let me use the former syntax?
For Dictionary<string, string> you can use Object.entries()
For List<KeyValuePair> object destructuring
const dictionaryObj = {
a: 'somestring',
b: 42,
};
for (const [key, value] of Object.entries(dictionaryObj)) {
console.log(`${key}: ${value}`); // DoSomeStuff(key, value)
}
console.log('===========================================');
const kvpList = [
{ key: '1', value: 'v1' },
{ key: '2', value: 'v2' },
{ key: '3', value: 'v3' },
];
for (const { key, value } of kvpList) {
console.log(`${key}: ${value}`); // DoSomeMoreStuff(key, value)
}
If you have an object and you want to iterate through its properties, then we can use Object.entries method to get an array of a given object's own enumerable string-keyed property [key, value] pairs, and then just use loop foreach:
let input = { "workType": "NDB To Nice", "priority": 5, "name": "Joseph", "lastName": "Skeet" }
const fooFunctiion = (key, value) => {
console.log(`key: ${key}, value ${value}` )
}
Object.entries(input).forEach(([k, v]) => {
fooFunctiion(k, v)
});
If you have an array of objects, then you can use foreach method:
let input = [
{ "workType": "NDB To Nice", "priority": 5 },
{ "workType": "PDAD", "priority": 0 },
{ "workType": "PPACA", "priority": 0 },
{ "workType": "Retrigger", "priority": "5" },
{ "workType": "Special Intake Request Intake", "priority": "7" }
];
const fooFunction = (obj, index) => {
console.log('obj: ', obj, index )
}
input.forEach((obj, ind) =>
fooFunction(obj, ind)
);

formatting dynamic json array

I have an json array as follows:
Maindata=[
{"name":"string1"},
{"name":"string2"},
{"name":"string3"}
];
what I need is an array of following type:
data=[
{
"name":"string1",
"name":"string2",
"name":"string3"
}
];
can anybody help me with some methods to obtain required json from original array.
(note: maindata is json array formed dynamically thats why its structure is like that)
Thanks in advance
You could use Object.assign and spread the array elements.
var array = [{ name1: "string1" }, { name2: "string2" }, { name3: "string3" }],
object = Object.assign({}, ...array);
console.log(object);
With reduce, you can do like following
var Maindata = [{
"name1": "string"
}, {
"name2": "string"
}, {
"name3": "string"
}];
var finalObj = Maindata.reduce((acc, cur) => {
Object.assign(acc, cur);
return acc;
}, {})
console.log(finalObj);
You can use Array.forEach or Array.reduce to iterate though the items of the Maindata object and for each item you can iterate through its keys(using Object.keys) and group the data into a new structure.(See the below snippet)
Solution using Array.forEach
var Maindata=[
{"name1":"string1"},
{"name2":"string2"},
{"name3":"string3"}
];
var result = {};
var newMaindata=[];
Maindata.forEach(function(el){
Object.keys(el).forEach(function(key){
result[key]=el[key];
});
});
newMaindata.push(result);
console.log(newMaindata);
Solution using Array.reduce
var Maindata = [{
"name1": "string1"
}, {
"name2": "string2"
}, {
"name3": "string3"
}];
var result ;
var newMaindata = [];
result = Maindata.reduce(function(acc,el) {
Object.keys(el).forEach(function(key) {
acc[key] = el[key];
});
return acc;
},{});
newMaindata.push(result);
console.log(newMaindata);

Categories