This question already has answers here:
Converting an Array to an Object
(3 answers)
Closed 2 years ago.
I am having troubles converting an array into an object of keys and values.
Currently, I have the following nested array:
var array = [[id1, parent1, "name1", "desc1"], [id2, parent1, "name2", "desc2"], [id3, parent1, "name3", "desc3"]];
Where the length of the array is dynamic.
For my code, I require the array to be converted such that it is an object of keys and values (consisting of the first (id) and third (name) value of each nested array).
For example, the object for the above array would be as follows:
var obj = {id1: name1, id2: name2, id3: name3};
Where the id values (id1, id2, id3) would be the corresponding integer values.
I apologise if a similar question has been asked before, but I couldn't seem to find a similar question which had a solution that worked for me.
Any help or advice would be greatly appreciated!
You can use a simple for loop to do it
var array = [
["id1", "parent1", "name1", "desc1"],
["id2", "parent1", "name2", "desc2"],
["id3", "parent1", "name3", "desc3"]
];
const obj = {}
for (const item of array) {
obj[item[0]] = item[2];
}
console.log(obj);
After using Array.map to extract the first and third entries from each element in the array, you can then use Object.fromEntries to convert the extracted array of key/value pairs into an object:
const [id1, id2, id3, parent1] = [1, 2, 3, 4];
const array = [
[id1, parent1, "name1", "desc1"],
[id2, parent1, "name2", "desc2"],
[id3, parent1, "name3", "desc3"]
];
const obj = Object.fromEntries(array.map(a => [a[0], a[2]]));
console.log(obj);
You basically want to convert your original array into an array of [key, value] pairs. You can then use the Object.fromEntries function to convert those key/values into an object. So, something like this:
const arr = [
["id1", "parent1", "name1", "desc1"],
["id2", "parent2", "name2", "desc2"],
["id3", "parent3", "name3", "desc3"],
];
const results = Object.fromEntries(arr.map(x => ([x[0], x[2]])))
console.log(results)
As a good practice, it is recommended to use let or const instead of var because var "pollute" the global namespace, so that's what my example will use.
However, if you need to use var, you can replace const with var inside my example and it will still be okay.
Given the following source array:
const array = [
[id1, parent1, "name1", "desc1"],
[id2, parent1, "name2", "desc2"],
[id3, parent1, "name3", "desc3"]
];
The following block of code create an object named obj using the 1st element of the sub-array as a key, and the 3rd element as the value:
// Create an empty object
const obj = {};
// Iterate through the source array
array.forEach((element) => {
// Assign the 1st element of the sub-array as the property key
// and the 3rd element as the property value
obj[element[0]] = element[2];
});
console.log(obj);
And this has the same effect, but simpler and with a smaller footprint:
const obj = Object.fromEntries(array.map(([key, _, value]) => [key, value]));
console.log(obj);
Related
I would like to know how to get particular key from object and convert to array
in javascript
var result = Object.entries(obj).includes(obj.name || obj.country || obj.account || obj.pincode).map(e=>e);
var obj = {
"name" : "Sen",
"country": "SG",
"key" : "Finance",
"city": "my",
"account":"saving",
"pincode":"1233"
}
Expected Output
["Sen", "SG", "saving", "1233"]
Create an array of requested keys, and then map it and take the values from the original object:
const obj = {"name":"Sen","country":"SG","key":"Finance","city":"my","account":"saving","pincode":"1233"}
const keys = ['name', 'country', 'account', 'pincode']
const result = keys.map(k => obj[k])
console.log(result) // ["Sen", "SG", "saving", "1233"]
I think you can try it like this.
There're other ways to get that result, too. Here's just a simple solution.
var obj = {
"name" : "Sen",
"country": "SG",
"key" : "Finance",
"city": "my",
"account":"saving",
"pincode":"1233"
}
let arrObj = []
let result = arrObj.push(obj.name, obj.country, obj.account, obj.pincode)
console.log(arrObj)
filter by a Set containing just the keys you want, then use map to return just the values:
const keys = new Set(['name', 'country', 'account', 'pincode'])
Object.entries(obj).filter(entry => keys.has(entry[0])).map(entry => entry[1])
If you want an array based on a known, hardcoded list of properties, the easiest option is an array literal:
const result = [obj.name, obj.country, obj.account, obj.pincode];
A benefit of this approach is that it guarantees the order of values in the array. While the order is predictable in your example (one onject literal), f your objs are created in different places, the order of the values may not always be the same.
var obj = {
"name" : "Sen",
"country": "SG",
"key" : "Finance",
"city": "my",
"account":"saving",
"pincode":"1233"
}
const Names = Object.keys(obj);
console.log(Names);
const Values = Object.values(obj);
console.log(Values);
const entries = Object.entries(obj);
console.log(entries);
I have a JSON response as below:
[{
"id": 1,
"food": {
"fruits": ["Banana", "Orange", "Apple", "Mango"],
"veggies": ["greens", "peppers", "carrot", "potatoes"],
}
},
{
"id": 2,
"food": {
"fruits": ["grapes", "berries", "peach", "pears"],
"veggies": ["cabbage", "spinach"],
"dairy": ["nutmilk", "goatmilk"]
}
}
]
Now i want to merge the Arrays each "id" (1,2 in example) into string ( ; delimited) like below:
id_1 = Banana;Orange;Apple;Mango;greens;peppers;carrot;potatoes
// observer "id_2" has additional array - "dairy"
id_2 = grapes;berries;peach;pears;cabbage;spinach;nutmilk;goatmilk
The key's are dynamic so for some records there are 2 arrays and for some records it can be 3 or 4 and may be 1.
I tried using react/Java Script Array.concat(), but i am not sure how to do it dynamically. Please help me. Thank you.
This is doable easily using Object.values().flat().join(';') demonstrated below:
let arr=[{"id":1,"food":{"fruits":["Banana","Orange","Apple","Mango"],"veggies":["greens","peppers","carrot","potatoes"],}},{"id":2,"food":{"fruits":["grapes","berries","peach","pears"],"veggies":["cabbage","spinach"],"dairy":["nutmilk","goatmilk"]}}];
const result = arr.map(({id,food}) => ({id, food: Object.values(food).flat().join(';')}));
console.log(result);
You may easily restructure the output by simply changing it to e.g. ["id_"+id]: Object.values(...)
First flatten using map, flat and join. Then convert the resulting array of objects to a single object using assign.
var db = [{"id": 1,"food": {"fruits": ["Banana", "Orange", "Apple", "Mango"], "veggies": ["greens","peppers","carrot","potatoes"], }},{"id" : 2,"food": {"fruits": ["grapes", "berries", "peach", "pears" ], "veggies": ["cabbage","spinach"], "dairy": ["nutmilk","goatmilk"]}}];
var flat = db.map(
({id, food}) => ({[`id_${id}`]: Object.values(food).flat().join(';')})
);
var result = Object.assign(...flat);
console.log(result);
This is really two problems: looping through an array of objects to combine them into one object, and looping through an object to concat all of its array.
Tackling the second one first, something like this would work:
const concatArraysInObject = obj =>
Object.values(obj).reduce((result, arr) => result.concat(arr), []);
const input = { a: [1,2,3], b: [4,5,6], c: [7,8,9] };
const output = concatArraysInObject(input);
console.log(output);
Object.values() will give you an array of all arrays in an object.
The reduce() function takes a two parameters: a function and initial value.
The function should also take (at least) 2 parameters: the result of the last call (or initial value) and the current value in the array.
It'll call the function once for each element in the array.
Now, with that solved, we can tackle the first problem.
For this, we can also use reduce() as well, and we'll construct our combined object on each call.
const concatArraysInObject = (obj) =>
Object.values(obj).reduce((result, arr) => result.concat(arr), []);
const mergeObjectsInArray = (arr, dataKey) =>
arr.reduce((result, obj) => ({ ...result, [obj.id]: concatArraysInObject(obj[dataKey]) }), {});
const input = [
{ id: 'A', data: { a: [1,2,3], b: [4,5,6] } },
{ id: 'B', data: { c: [7,8,9], d: [10,11,12] } }
];
const output = mergeObjectsInArray(input, 'data');
console.log(output);
An important note of warning: object key order is NOT guaranteed in JavaScript. While 99% of the time they will be in the order you expect, this is not a guarantee, so if you depend on the order of the keys for the order of the array (if order matters), you'll want to change your input structure. If order doesn't matter, it is probably fine how it is.
Try this using basic for loop. Inside you will compute key dynamically and value being flattened array of Object.values of the iterating object.
var input = [{
id: 1,
food: {
fruits: ["Banana", "Orange", "Apple", "Mango"],
veggies: ["greens", "peppers", "carrot", "potatoes"]
}
},
{
id: 2,
food: {
fruits: ["grapes", "berries", "peach", "pears"],
veggies: ["cabbage", "spinach"],
dairy: ["nutmilk", "goatmilk"]
}
}
];
var temp = [];
for (var i = 0; i < input.length; i++) {
temp.push({
[`id_${input[i].id}`]: Object.values(input[i].food)
.flat(1)
.join(";")
});
}
console.log(temp); // this gives you an array
console.log(Object.assign(...temp));// in case you require one single object
I have a JSON array of objects in JS that look something like this:
"data": [
{"name": "abc", "location": "NY", "value": 1234, "potato": "tomato", "someOtherProp": "prop1"},
{"name": "def", "location": "CA", ... etc}
{etc ...},
]
I'm creating a UI for filtering down some of these fields and want to create an array for each attribute with all the given values in the data.
I know this is possible using something like this:
let result = objArray.map(a => a.name);
But using this strategy, I have to run map once for every property. Is there any way to only go through the array once but create a separate array for each? (Or is there a better way in general for creating filter options for a UI?)
To clarify, for the array above, I'd want an array for "names" (containing "abc" and "def"), an array for "locations" (containing NY, CA, etc.) an array for "potato"s and "someOtherProp".
I appreciate any help!
Thanks
Loop through the array with .reduce(). In each iteration, loop through the keys of the object using Object.keys(), adding any unique values to an array of the same name.
This solution eliminates duplicate entries and works with any amount of properties.
const data = [{name: "abc", location: "NY"},{name: "def", location: "CA"},{name: "xyz", location: "TX"},{name: "zyx", location: "TX"}];
const getFiltersFromData = (data) => {
return data.reduce((out,obj) => {
Object.keys(obj).forEach(k => {
if (out[k] === undefined) out[k] = [obj[k]]; //Array doesn't exist yet - instantiate it
else if (!out[k].includes(obj[k])) out[k].push(obj[k]); //Array exists and this value isn't in it - add the value to it
});
return out;
}, {});
};
const filters = getFiltersFromData(data);
console.log(filters.name);
console.log(filters.location);
.as-console-wrapper, .as-console { height: 100% !important; max-height: 100% !important; top: 0; }
You could create the separate arrays from names, locations and values and then use map on the data array to push each attribute value to the arrays. You can do that vs. running map multiple times for each property:
var names = [];
var locations = [];
var values = [];
data.map((elt) => {
names.push(elt.name);
locations.push(elt.location);
values.push(elt.value);
});
Try with Object.entries
You can get something like this:
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
I have two arrays:
The first contains unique names of fields in a nested array:
[0][0]:Name1
[0][1]:Name2
[0][2]:Name3
etc.
The second contains multiple items with values in a nested array like this:
[0][0] XYZ
[0][1] XYZA
[0][2] XYZ2
[1][0] XYZaa
[1][1] XYZas
[1][2] XYA
etc
What I want to do is to merge it and name it in this way:
[0] Name1: XYZ
[0] Name2: XYZA
[0] Name3: XYZ2
[1] Name1: XYZaa
[1] Name2: XYZas
[1] Name3: XYA
To achieve this I first attempted the following:
var mergedArr = name.concat(data);
That works fine, however I believe I can also use lodash to get closer to what I want:
_.merge(name, data)
and should work fine too.
I was trying to name it by using
_.zipObject
Yet it doesn't work the way I would like
I was trying few options with zip, zipObject, yet non of it gave me expected output.
Edit1:
how I created arrays:
$("#T1020 tr").each(function(x, z){
name[x] = [];
$(this).children('th').each(function(xx, zz){
name[x][xx] = $(this).text();
});
})
$("#T1020 tr").each(function(i, v){
data[i] = [];
$(this).children('td').each(function(ii, vv){
data[i][ii] = $(this).text();
});
})
If I understand your question correctly, you're wanting to zip array1 and array2 into a single array where:
each item of the result array is an object
the keys of each object are values of array1[0], and
the values of each key corresponding nested array of array2
To produce the following:
[
{
"name1": "xyz",
"name2": "xyza",
"name3": "xyz2"
},
{
"name1": "xyzaa",
"name2": "xyzas",
"name3": "xya"
}
]
This can be achieved without lodash; first map each item of array2 by a function where array1[0] is reduced to an object. The reduced object is composed by a key that is the current reduce item, and a value that is taken from the indexed value of the current map item:
const array1 = [
['name1', 'name2', 'name3']
]
const array2 = [
['xyz', 'xyza', 'xyz2'],
['xyzaa', 'xyzas', 'xya']
]
const result = array2.map((item) => {
/* Reduce items of array1[0] to an object
that corresponds to current item of array2 */
return array1[0].reduce((obj, value, index) => {
return { ...obj,
[value]: item[index]
};
}, {});
});
console.log(JSON.stringify(result, null, ' '));
Iterate the values (your array2) and take the sub-array from the keys (array) using the current index and the % operator. This will ensure that if that the keys are taken in a cyclic way (see example with keys2 and values2). Convert to object with _.zipObject:
const fn = (keys, values) => values.map((v, i) => _.zipObject(keys[i % keys.length], v))
const keys1 = [['name1', 'name2', 'name3']]
const values1 = [['xyz', 'xyza', 'xyz2'], ['xyzaa', 'xyzas', 'xya']]
const keys2 = [['name1', 'name2', 'name3'], ['name11', 'name12', 'name13']]
const values2 = [['xyz', 'xyza', 'xyz2'], ['xyzaa', 'xyzas', 'xya'], ['abc', 'def', 'hij']]
console.log(fn(keys1, values1))
console.log(fn(keys2, values2))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
How can I set a jsonarray inside the jsonobject?
I want to be able to push the values but I do not know exactly what to do
sample :
{
"ContactsDetails": [
{
"Prefix": "string",
"FirstName": "string",
"LastName": "string",
"Mobile": "string",
"EmojiId": "byte"
}
],
"GroupId": integer
}
Here is the sample code what you're looking for.
let empty = {}; // init a empty object.
empty["ContactsDetails"] = []; // array creation
empty["GroupId"] = 45; // number adding
// creating a new object
let c_details = {
"Prefix": "string",
"FirstName": "string",
"LastName": "string",
"Mobile": "string",
"EmojiId": "byte"
};
// adding an existing obj to array, push operation
empty["ContactsDetails"].push(c_details);
// print object
console.log(empty);
// this will convert the object to JSON.
console.log(JSON.stringify(empty))
What you call a JSONArray is simply a Javascript array like []. You can set it like any property of an Object (JSON).
In Javascript, an Object (symbolized as {}) will be represented as a JSON Object and a Array (symbolized by []) will be represented as a JSON Array.
So you can just do something like this :
var object = {};
object.foo = [];
object.foo.push("newvalue");
object.foo.push("bar");
console.log(object);
And of course, you can push an Object in your array like this :
var array = [];
array.push({ foo: "bar" });
console.log(array);
Arrays and objects are structures that can recursively contain themselves, or each other. JSON is just a format that represents these recursive data structures.
Luckily, you can define all of these in JavaScript using plain literals:
An array literal is wrapped within brackets []
An object literal is wrapped within curly brackets {}
Hence, you can build an array of objects:
[
{name: 'x', data: 0},
{name: 'y', data: 1}
]
Or an object that its parameters are arrays:
{
array0: [0, 1],
array1: [2, 3]
}
And, as I mentioned above, you can also use these structures recursively. For example:
[
{id: 0, array: [0, 1]},
{id: 1, array: [2, 3]}
]