Convert an array to nested object using Lodash, is it possible? - javascript

I have an array:
["a", "b", "c", "d"]
I need to convert it to an object, but in this format:
a: {
b: {
c: {
d: 'some value'
}
}
}
if var common = ["a", "b", "c", "d"], I tried:
var objTest = _.indexBy(common, function(key) {
return key;
}
);
But this just results in:
[object Object] {
a: "a",
b: "b",
c: "c",
d: "d"
}

Since you're looking for a single object out of an array, using _.reduce or _.reduceRight is a good candidate for getting the job done. Let's explore that.
In this case, it's going to be hard to work from left to right, because it will require doing recursion to get to the innermost object and then working outward again. So let's try _.reduceRight:
var common = ["a", "b", "c", "d"];
var innerValue = "some value";
_.reduceRight(common, function (memo, arrayValue) {
// Construct the object to be returned.
var obj = {};
// Set the new key (arrayValue being the key name) and value (the object so far, memo):
obj[arrayValue] = memo;
// Return the newly-built object.
return obj;
}, innerValue);
Here's a JSFiddle proving that this works.

Related

How to convert array data to new data [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have an initalArray that looks like this:
initailArray: ["a", "b", "c", "d"]
Say I want to convert a -> apple, b -> berry c -> cat and d -> dog
so my newArray should look like this:
newArray: ["apple", "berry", "cat", "dog"]
Is there a way I could do this? I think I need to use if or switch. But
don't know exactly how.
you could use map to go over the initialArray, like this:
let initialArray = ["a", "b", "c", "d"];
let newArray = initialArray.map(item => {
switch(item) {
case 'a':
return 'apple';
break;
case 'b':
return 'berry'
break;
case 'c':
return 'cat';
break;
case 'd':
return 'dog';
break;
}
});
Hope this helps.
You can use Array.map to convert each item to the item from a given mapping.
const mapping = {
a: 'apple',
b: 'berry',
c: 'cat',
d: 'dog'
};
const initialArray = ["a", "b", "c", "d"];
const result = initialArray.map(entry => mapping[entry]);
console.log(result);
First of all you need to have a "map" from codes ("a", "b" ecc...) and your values ("apple", "berry" ...):
let myMap = { a: "apple", b: "berry", c: "cat", d:"dog" };
Then you can use the "map" method of Array:
let newArray = initialArray.map((key) => myMap[key]);
let initialArray = ["a","b","c","d"];
let myMap = { a: "apple", b: "berry", c: "cat", d:"dog" };
let newArray = initialArray.map((key) => myMap[key]);
document.write(JSON.stringify(newArray));
You could just use an object as a map that contains each letter and their corresponding values.
Then you could use Array#map and for each letter return the respective value from the map.
/* #type {{[letter: string]: string}} Map of letters and corresponding values */
var alphabetMap = {
"a": "apple",
"b": "berry",
"c": "cat",
"d": "dog",
};
var initialArray = ["a", "b", "c", "d"];
// transform array of letters to array of respective values
console.log(initialArray.map(function(letter) {
// for each letter return value of `alphabetMap` for that letter
return alphabetMap[letter] || "Invalid Letter"; // Nice to have a default value
}));
const mapping = {
a: 'apple',
b: 'berry',
c: 'cat',
d: 'dog'
};
const result = ["a", "b", "c", "d"].map(ele=>mapping[ele]);
console.log(result);
You can try this
for (i = 0; i < initailArray.length; i++){
if(initailArray[i] == "a"){
initailArray[i] == "apple"
}
else if (initailArray[i] == "b"){
initailArray[i] == "berry"
}
else if (initailArray[i] == "c"){
initailArray[i] == "cat"
}
else if (initailArray[i] == "d"){
initailArray[i] == "dog"
}
}

How to get the key for a array with his value is equal True

I'm trying to get all the keys on my Object with a value "T" (true) and show them in the component but i'm getting troubles.
I tried with for and forEach but I can't get the keys.
This is my render method and this is the object
render(){
const races = this.state.data.racesTrack.Races;
const racesList = [];
}
I need to see it like this
exacta
hq
place:
quinella
show:
spr:
trifecta:
wps:
Image with the object: https://i.stack.imgur.com/en09V.png
You can do something like this in ES6:
var raceList = []
var races = {
a: "T",
b: "F",
c: "T",
d: "F"
}
for (key in races) {
if (races[key] == "T") {
raceList.push(key)
}
}
console.log(raceList)
The problem you are asking is not related to Reactjs and is about the basics of javascript.
A simpler solution can be using Object Keys Array and the Filter method:
var race = {
a: "T",
b: "F",
c: "T",
d: "F"
}
var sort = Object.keys(race).filter((key)=>{
return race[key]==='T'
})
console.log(sort)

in Object.keys(obj) works only part time

Im trying to look if a number is in the Object.keys() for some reason I get a partial response some of the numbers are not included in the final object. Any idea why in works only partially here?
var arrayOfNumbersIHave = [
"542009988",
"7411111111",
"542261111",
"542009988",
"7411111111",
"7411111111",
"7442334675",
"661766029",
"692549335",
]
var snapObject = {
"542009988": "A",
"542261111": "B",
"661766029": "C",
"6617666029": "D",
"692549335": "E",
"7442334675": "F",
"7411111111": "G",
}
var objToDisplay = {};
for (const i in arrayOfNumbersIHave) {
if (i in Object.keys(snapObject)) {
objToDisplay[arrayOfNumbersIHave[i]] = snapObject[arrayOfNumbersIHave[i]]
}
}
console.log(objToDisplay)
Result:
{
"542009988": "A",
"542261111": "B",
"7442334675": "F",
"7411111111": "G",
}
Expected result:
{
"542009988": "A",
"542261111": "B",
"661766029": "C",
"692549335": "E",
"7442334675": "F",
"7411111111": "G",
}
You can avoid using for..in to iterate an array. Alternatively you can use reduce on the arrayOfNumbersIHave & in each iteration curr parameter will represent each element of arrayOfNumbersIHave. Use this curr to check if there exist a key by same name in snapObject. Is so then in the accumulator object add the key and value
let arrayOfNumbersIHave = [
"542009988",
"7411111111",
"542261111",
"542009988",
"7411111111",
"7411111111",
"7442334675",
"661766029",
"692549335",
]
let snapObject = {
"542009988": "A",
"542261111": "B",
"661766029": "C",
"6617666029": "D",
"692549335": "E",
"7442334675": "F",
"7411111111": "G",
}
let objToDisplay = arrayOfNumbersIHave.reduce(function(acc, curr) {
if (snapObject[curr]) {
acc[curr] = snapObject[curr]
}
return acc;
}, {}) // {} is accumulator object
console.log(objToDisplay)
Using the in operator in that manner is not quite correct. in checks for either properties in objects or indices in an array. So it is probably returning true only when the number you are checking happens to be an index in the array.
So for this case, you really want to omit the Object.keys and instead use:
for (const i in arrayOfNumbersIHave) {
if (arrayOfNumbersIHave[i] in snapObject) {
objToDisplay[arrayOfNumbersIHave[i]] = snapObject[arrayOfNumbersIHave[i]]
}
}
And as #adiga points out below, we can simplify this with a for...of loop, to get:
for (const val of arrayOfNumbersIHave) {
if (val in snapObject) {
objToDisplay[val] = snapObject[val];
}
}
You need to check the value of the array, if this is in the object, not by taking an index and look if the index is in an array.
This line
if (arrayOfNumbersIHave[i] in snapObject) {
takes the value of arrayOfNumbersIHave[i] as key for checking with in operator and an object.
var arrayOfNumbersIHave = ["542009988", "7411111111", "542261111", "542009988", "7411111111", "7411111111", "7442334675", "661766029", "692549335"],
snapObject = { 542009988: "A", 542261111: "B", 661766029: "C", 6617666029: "D", 692549335: "E", 7442334675: "F", 7411111111: "G" },
objToDisplay = {};
for (const i in arrayOfNumbersIHave) {
if (arrayOfNumbersIHave[i] in snapObject) {
objToDisplay[arrayOfNumbersIHave[i]] = snapObject[arrayOfNumbersIHave[i]];
}
}
console.log(objToDisplay);
You can just simply iterate on first array, and check if the current item has any presence in snapObject, if so, just create an entry (key) in your objToDisplay and assign matched value:
arrayOfNumbersIHave.forEach(function(number) {
if (snapObject[number]) objToDisplay[number] = snapObject[number];
});

Destructuring for get the first property of an object?

For arrays, we can define the properties depending on it's indexes like:
const arr = [1, 2, 3];
const [first, second, third] = arr;
console.log(first, second, third)
I'm just wondering if there's a possible solution to do it's reverse with objects like:
const obj = {first: "a", second: "b", third: "c"}
const {0, 1, 2} = obj;
//expected: "a", "b", "c"
You do it like this for objects:
const obj = {foo: 123, bar: 'str'}
const {foo, bar} = obj
It isn't.
Objects are not designed to be ordered, so there isn't a first property per se.
You could convert an object into an array of its values first …
const obj = {
first: "a",
second: "b",
third: "c"
}
const array = Object.values(obj);
const [foo, bar, baz] = array;
console.log({
foo,
bar,
baz
});
… but it is unlikely to be useful and it certainly wouldn't be intuitive code that is easy to maintain.
Try this:
const obj = {first: "a", second: "b", third: "c"}
const indexes = [0, 1, 2]
indexes.map( (val) => { return Object.values(obj)[val] } ) //["a", "b", "c"]
You could take the values and assign this to an array for destructuring.
The order is actually dtermined by the insertation order or if a key is like a valid index of an array, it is sorted numerically to top.
const
object = { first: "a", second: "b", third: "c" },
[first, second, third] = Object.values(object);
console.log(first, second, third);
For extracting a an arbitrary position, you vould take an object with an index an object property assignment pattern [YDKJS: ES6 & Beyond] for a new valid variable.
const
object = { first: "a", second: "b", third: "c" },
{ 2: foo } = Object.values(object);
console.log(foo);

Sorting an Array of JavaScript Objects a Specific Order (using existing function)

Given an array of objects:
{
key: "a",
value: 42
},
{
key: "d",
value: 28
},
{
key: "c",
value: 92
},
{
key: "b",
value: 87
}
and an array of keys:
["c", "a", "b", "d"]
Is there a ECMAScript function or a 3rd-party JavaScript library that lets you sort - in one line/function call - the first array of objects, to match the order of the keys specified in the second array, such that the result is:
{
key: "c",
value: 92
},
{
key: "a",
value: 42
},
{
key: "b",
value: 87
},
{
key: "d",
value: 28
}
Other questions that provide a function or algorithm:
Javascript - sort array based on another array - Stack Overflow
javascript - How do I sort an array of objects based on the ordering of another array? - Stack Overflow
Similar/related questions:
Sorting an Array of Objects in PHP In a Specific Order
php - Sort array of objects
Just use indexOf to convert the key to the correct order:
var order = ["c", "a", "b", "d"];
_.sortBy(arr, function(obj){
return _.indexOf(order, obj.key);
});
Fiddle
If there are a lot of keys, then it would be advantageous to make a hash-map out of the array, like:
var order = ["c", "a", "b", "d"];
var orderMap = {};
_.each(order, function(i) { orderMap[i] = _.indexOf(order, i); });
This makes the key-sorting lookup constant time rather than O(n). (Fiddle)
Great answers provided so far. Thought that the following may also be an alternative solution in plain JS:
var arr = arr.sort(function(a,b) {
return order.indexOf( a.key ) - order.indexOf( b.key );
//for the sake of recent versions of Google Chrome use:
//return a.key.charCodeAt(0) > b.key.charCodeAt(0); or return a.key.charCodeAt(0) - b.key.charCodeAt(0);
});
var arr = [
{
key: "a",
value: 42
},
{
key: "d",
value: 28
},
{
key: "c",
value: 92
},
{
key: "b",
value: 87
}
];
var order = ["c", "a", "b", "d"];
console.log( 'Original: ', JSON.stringify( arr ) );
var arr = arr.sort(function(a,b) {
return order.indexOf( a.key ) - order.indexOf( b.key );
});
console.log( 'Ordered: ', JSON.stringify( arr ) );
const obj = [
{
key: "a",
value: 42
},
{
key: "d",
value: 28
},
{
key: "c",
value: 92
},
{
key: "b",
value: 87
}
]
const sortList = ["c", "a", "b", "d"];
const sortedObj = obj.sort((a, b) => {
return (
sortList.indexOf(a.key) - sortList.indexOf(b.key)
);
});
console.log(sortedObj );
I can't claim that this is the most efficient way, but you can use the key for each object as a key for properties in another object. Then simply access them by these keys.
for (x = 0; x < objn.length; x++) {
newobj[objn[x].key] = objn[x];
}
objn = [];
for (x = 0; x < keys.length; x++) {
objn.push(newobj[keys[x]]);
}
console.log(objn);
http://jsfiddle.net/WdehF/
// create hash map el.key -> index, to help us with direct access, avoid searching
const hashMap = arr.reduce((acc, el, index) => { acc[el.id] = el; return acc }, {})
// finally, map the ids to the final result
const ids.map(id => hashMap[id])
const data = [{key:"a"},{key:"d"},{key:"c"},{key:"b"}] // <-your data
const order = ["c", "a", "b", "d"] // <-create an array in the order you wish
const orderedArray = order.map(char=>data.find(res=>res.key===char)) // <- what you want
For each char in order: it will map if the char is equal to any key found within your data, and return it, consecutively

Categories

Resources