This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Javascript: How to Get Object property using Array of string? [duplicate]
(7 answers)
Set nested item in object/array from array of keys
(4 answers)
Closed 3 years ago.
I have a JavaScript object, that is multiple levels deep, for example:
let obj = [
{
"testKeyOne": "one",
"testKeyTwo": "two"
},
{
"testKeyThree": "three",
"testKeyFour": "four",
"testKeyFive": {
"testKeyFiveAndAHalf": "5.5"
"testKeyFiveAndThreeQuarters": "5.75"
}
},
]
I also have an array for the key of what I need to access, for example, if I'm looking for the 5.5 one,
let array = [1, "testKeyFive", "testKeyFiveAndAHalf"]
though my array may also look like this if I'm looking for "one"
let array = [0, "testKeyOne"]
Is there any way to use the array to access the desired value?
This is my first time asking a question so if I messed up or if there is anything unclear or something that needs to be changed I apologize.
Thank you!
Yep. You can just use a reduce on the array:
let result = array.reduce((value, entry) => value[entry], obj);
let desired = obj;
while(array.length > 0) { desired = desired[array[0]]; array.shift() }
console.log(desired)
this should work
Here's one way to do it:
let obj = [{
"testKeyOne": "one",
"testKeyTwo": "two"
},
{
"testKeyThree": "three",
"testKeyFour": "four",
"testKeyFive": {
"testKeyFiveAndAHalf": "5.5",
"testKeyFiveAndThreeQuarters": "5.75"
}
},
]
let arr = [
[1, "testKeyFive", "testKeyFiveAndAHalf"],
[0, "testKeyOne"]
]
function foo(objArr, accessArr) {
for (const [index, ...keys] of accessArr) {
let obj = objArr[index];
for (const key of keys) {
obj = obj[key];
}
console.log(obj)
}
}
foo(obj, arr);
You can use a recursive function like that
let obj = [{
testKeyOne: "one",
testKeyTwo: "two"
},
{
testKeyThree: "three",
testKeyFour: "four",
testKeyFive: {
testKeyFiveAndAHalf: "5.5",
testKeyFiveAndThreeQuarters: "5.75"
}
}
];
let array = [1, "testKeyFive", "testKeyFiveAndAHalf"];
function getValue(arr, obj) {
const [first, ...rest] = arr;
return typeof(obj[first]) === "object" ? getValue(rest, obj[first]) : obj[first];
}
console.log(getValue(array, obj));
Related
Is there any operation in Javascript just like [x for x in array] in python?
For example, I'm using javascript to reading a json file where there're dozens of (key, value) pairs needed to be handled(or transformed into other format). And I thought working in this way is stupid:
let transformed = []
for (let key in json){
transformed = [ /* doing some transform*/ ]
}
Is there anything like:
let transformed = [
lambda function1(key), lambda function2(value) for key, value in json
]
Thanks in advance.
The rough equivalent of Python's list comprehension is Array.map:
const myArray = [1, 2, 3]
const transformed = myArray.map((item) => item + 1)
// [2, 3, 4]
But your example is not about an array, but about an Object with keys and values. In Python, this would be a dict, and you'd use a dict comprehension along the lines of {function1(key): function2(value) for key, value in my_dict.items()}.
In JavaScript, you can turn such an object into an array with Object.entries, then perform the map, and finally transform it back into an object using Object.fromEntries:
const myObject = { a: 1, b: 2 }
const transformed = Object.fromEntries(Object.entries(myObject)
.map(([key, value]) => [key + 'x', value + 1]))
// { ax: 2, bx: 3 }
Note that fromEntries is fairly new and you might need to add a polyfill for it.
You can use a code likes this. You must use a function that handle operation on current single item.
const words = ['hello', 'bird', 'table', 'football', 'pipe', 'code'];
const capWords = words.forEach(capitalize);
function capitalize(word, index, arr) {
arr[index] = word[0].toUpperCase() + word.substring(1);
}
console.log(words);
// Expected output:
// ["Hello", "Bird", "Table", "Football", "Pipe", "Code"]
First of all, javascript does NOT support Associative Arrays. If you are used to them in Python, PHP, and other languages you need to do a little workaround in JS to achieve the same functionality.
The most common way to simulate an associative array is using an object.
let testObject = {name: "Color", value: "Red"};
And then you push every object into an array so you end up with something like this:
let testArray = [{name: "Color", value: "Red"}, {name: "Color", value: "Blue"}];
Once you have this array consisting of objects, you can use map function to go through every object in the array and do whatever you want with it.
testArray.map((item, index) => {
console.log("The value of "+index+". item is: "item.value);
})
You can use Array.map() function. It work pretty like Array.forEach() function
const numbers = [1, 2, 3, 4, 5]
let newArray = numbers.map((element) => {
return element * 2
})
console.log(newArray) // excepted : [ 2, 4, 6, 8, 10 ]
It can be reduce using
const numbers = [1, 2, 3, 4, 5]
let newArray = numbers.map(element => element * 2)
console.log(newArray) // excepted : [ 2, 4, 6, 8, 10 ]
For more informations, you can this documentation https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/map
I have an array containing objects that every element but the last one are objects, but I want to convert them into an array of arrays and add the last element.
To be more explicit here is how I have it:
[
{ 0: [1,2], 1: [6,2], name: "" },
{ 0: [3,4], 1: [2,2], name: "" }
]
and the result I want is this one:
[
{ multipolygon: [ [1,2], [6,2] ], name: ""},
{ multipolygon: [ [3,4], [2,2] ], name: ""}
]
Each single array contained inside the original array is converted into an array of those arrays.
I have tried doing this:
const zonesArray = zones.map(el => Object.values(el)) // obj => array
const polygons = zonesArray.filter(el => el.pop()) // array without name
to get all the arrays contained inside the obj but then I realized how can I replace this into the original objects.
I have tried to modify the groupBy function found on MDN:
function groupBy(objectArray, property) {
return objectArray.reduce(function (acc, obj) {
let key = obj[property]
if (!acc[key]) {
acc[key] = []
}
acc[key].push(obj)
return acc
}, {})
}
But I can't seem to find the answer
It doesn't look like you're trying to group by a property, you're trying to transform each object in the array separately - which can be done by taking the name and the numeric properties together when mapping, then returning the shape of the new object:
const arr = [
{ 0: [1,2], 1: [6,2], name: "" },
{ 0: [3,4], 1: [2,2], name: "" }
];
const result = arr.map(({ name, ...rest }) => ({
name,
multipolygon: Object.values(rest)
}));
console.log(result);
Given this Object in Javascript
{
"0": "hello",
"1": { text: "world" }
}
What's the shortest way to create this array from that object?
[
"hello",
{ text: "world" }
]
I've seen somebody using Array.prototype.splice(theObject) but it doesn't seem to work for me.
Update:
Order of output needs to be guaranteed
0 and 1 can be any arbitrary string value and the order at property level needs to be maintained in the corresponding array.
Needs to work with Node.js 6
Just use Object.values:
console.log(Object.values({
"0": "hello",
"1": { text: "world" }
}));
If you want to be sure that the original keys of the object correspond to the positions in the resulting array, you can't rely on Object.values() or a for ... in loop. You can use Object.keys() and sort that array.
var keys = Object.keys(yourObject);
keys.sort();
var array = keys.map(key => yourObject[key]);
Now understand that the call to .sort() can include a comparator function to impose any ordering desired on the original object keys. The sample in the OP is very simple, and the above would work. However more complicated keys might require a custom comparator.
This should maintain the order based on the keys, including where keys have more than one digit
const test = {
"0": "hello",
"3": "three",
"1": { text: "world" },
"2": "two",
"11": "eleven",
}
const transform = obj => Object.keys(obj)
.sort((a, b) => parseInt(a) > parseInt(b) ? 1 : -1)
.map(key => obj[key])
console.dir(transform(test))
let src = {
"0": "hello",
"1": {
text: "world"
}
}
let res = [src].map(it => [it['0'], it['1']])
console.log(res)
Try using for..in loop like this:
let obj = {
"0": "hello",
"1": { text: "world" }
}
let result = []
for(var value in obj){
result.push(obj[value])
}
This question already has answers here:
How to convert an array of objects to object with key value pairs
(7 answers)
How to convert an array of key-value tuples into an object
(14 answers)
Closed 5 years ago.
I would like to turn this:
let myArray = [ {city: "NY"}, {status: 'full'} ];
to this:
let myObj = { city: "NY", status: 'full' };
while I tried this:
let newObj = {};
for (var i = 0; i < myArray.length; i++) {
(function(x) {
newObj = Object.assign(myArray[i]);
})(i);
}
it assigns the last pair to the object
Spread the array into Object#assign:
const myArray = [ {city: "NY"}, {status: 'full'} ];
const myObj = Object.assign({}, ...myArray);
console.log(myObj);
Note: Assign into an empty object. If you omit the empty object, the 1st element of the original array will be mutated (everything will be merged into it).
You could also use Array.reduce() which will give you more fine grain control:
const myArray = [
{ city: 'NY', color: 'blue', rodents: { small: false, medium: false, large: true } },
{ status: 'full', color: 'red' },
{ sandwich: 'flavourful' },
]
// item is each object in your array
const reduced = myArray.reduce((newObj, item) => {
// existing props will be overwritten by newer object entries in the array
// this example is same as Object.assign spread with right to left precedence,
// until you want more custom logic
Object.keys(item).forEach((key) => { newObj[key] = item[key] })
return newObj
}, {})
console.log(reduced)
// you will see `red` overwrite `blue`
EDIT: after examining this answer after a year, I note that it isn't optimized at all for ability to deep clone or deep merge. I recommend studying those aspects closer and to be careful of copying or breaking references if you are working immutably.
There is no issue with this in the above example because all values are primitives.
I would tend to agree with Ori that your question seems to be about creating an indexed object which isn't usually a good plan, but if its necessary to key your object with numbers you can do it like this:
let newObj = {};
myArray.forEach((val, index) => { newObj[index] = val });
let myArray = [ {city: "NY"}, {status: 'full'} ];
let newObj = myArray.reduce((acc, curr) => {
Object.keys(curr).forEach(val => {
acc[val] = curr[val]
})
return acc
}, {})
console.log(newObj)
This syntax is supported in IE according to caniuse.com
This question already has answers here:
Convert Array to Object
(46 answers)
Closed 6 years ago.
I have an array, say [{ id: 'first' }, { id: 'second' }]
Are there any native methods I'm missing that will convert the array into an array-like object? I've seen plenty of answers asking about the other direction, and recommending Array.prototype.slice.call (or the newer Array.from), but I can't find anyone asking about this. For the above example, I'd want to get the following output:
{
0: { id: 'first' }
1: { id: 'second' }
}
Reducing it
var array = [{ id: 'first' }, { id: 'second' }];
var obj = array.reduce( (a,b,i) => {return a[i]=b,a},{})
console.log(obj)
Check out the documentation on Array.reduce on MDN (Mozilla Developer Network)
You could just iterate through the array and add the values to the respective index
var arr = [{ id: 'first' }, { id: 'second' }];
var set = {};
arr.forEach(function(value, index){
set[index] = value;
})
console.log(set)
Not a native method, but the following helper function should do the trick:
var arr = [{ id: 'first' }, { id: 'second' }];
function toArrayLike(arrayToConvert) {
var retVal = {};
Object.keys(arrayToConvert).forEach(function(key) {
retVal[key] = arrayToConvert[key];
});
return retVal
}
var arrayLike = toArrayLike(arr);
console.log(arrayLike);