How to convert a 2D Javascript array to object with identifiers - javascript

What's the best way to convert a 2D array into an object with identifiers that count up?
There could be an unlimited number of identifiers in the object - based on what's in the array.
So in the array we might have
data: [
["Lisa", "Heinz"],
["Bob", "Sleigh"]
]
And we'd be keen that the array looked something like this in the end:
data: {
person1 {
{name: Lisa},
{last_name: Heinz}
},
person2 {
{name: Bob},
{last_name: Sleigh}
}
}
Using map I can create an array of objects, but this isn't quite
json = formData.map(function(x) {
return {
"name": x[0],
"last_name": x[1]
}
})
console.log(json);

Something like this? I changed your object structure a bit to be easier to access.
let newDataObj = {}
for (let person of data) {
const identifier = `person${data.indexOf(person)}`;
const [name, last_name] = person;
newDataObj[identifier] = { name, last_name };
}

Related

JS - How to add key:value pairs from objects nested in arrays to other objects nested in another array

I know it has been countlessly asked and I assure you that I've read a lot of posts, articles, etc., and watched a lot of videos but nothing seems to click.
so there we go :
Here are 2 arrays with partial information about every person
let arr1 = [{id:00, name:Ben, city:Philadelphia}, {id:01, name:Alice, city:Frankfurt}, {id:02, name:Detlef, city:Vienna}]
let arr2 = [{id:02, age:18}, {id:00, age:39}, {id:01, age:75}]
And there is the desired final result: an array including the name, city, and age of each person
let arr3 = [{name:Ben, city:Philadelphia, age:39}, {name:Alice, city:Frankfurt, age:75 }, {name:Detlef, city:Vienna, age:18}]
What's the situation? Two arrays both containing objects. each nested object has an id. That id is the common key in each array of objects.
What do you want to do? : I want to create a third array including information from both arrays (from arr1: name and city; from arr2:age).
What have you tried so far? : I couldn't manage to achieve anything worth showing. this minimal example is intended to show you a simple example of my current situation which is: I've got an array that is in the LocalStorage on one hand and an API on the other, both contain some info regarding particular objects (let's say, persons). I want to create an array that will contain all the information regarding each person for easier manipulation afterward (DOM generation, etc.).
I've managed to store both arrays in two "local" arrays but the problem is still there: I can't figure out how to make an array where items are getting their key/value from two separate sources.
Thank you for your help!
You can use reduce method on the arr with array as an inital value, and inside try to find the corrospending item with same id and destruct the object from the id and merge the two object with spread operator.
let arr1 = [{id:00, name:'Ben', city: 'Philadelphia' }, {id:01, name:'Alice', city:'Frankfurt'}, {id:02, name:'Detlef', city:'Vienna'}]
let arr2 = [{id:02, age:18}, {id:00, age:39}, {id:01, age:75}]
const result = arr1.reduce((acc, { id: id1, ...rest1 }) => {
const { id: id2, ...rest2 } = arr2.find(i => i.id === id1)
acc.push({ ...rest1, ...rest2 })
return acc;
}, [])
console.log(result)
You can solve it in various ways, here first I have implemented a dict with key as id to get the value in O(1) while iterating arr2.
So the overall time complexity is O(n+k) where n is len of arr1 and k is len of arr2.
let arr1 = [{id:00, name: "Ben", city: "Philadelphia"}, {id:01, name:"Alice", city:"Frankfurt"}, {id:02, name:"Detlef", city:"Vienna"}];
let arr2 = [{id:02, age:18}, {id:00, age:39}, {id:01, age:75}];
const refMapById = arr1.reduce((refMap, {id, name, city}) => {
refMap[id] = {name, city};
return refMap;
}, {});
const result = arr2.reduce((resultArray, {id, age}) => [...resultArray, { ...refMapById[id],age}], []);
console.log(result);
Cheers!
It will be worth creating a dictionary from one of the arrays anyway since using .find() inside of .reduce() adds an unnecessary nested loop. But instead of reducing the second array as was suggested you can simply .map() it into the result array, like so:
let arr1 = [{ id: 00, name: "Ben", city: "Philadelphia" }, { id: 01, name: "Alice", city: "Frankfurt" }, { id: 02, name: "Detlef", city: "Vienna" }];
let arr2 = [{ id: 02, age: 18 }, { id: 00, age: 39 }, { id: 01, age: 75 }];
const groupedById = arr1.reduce((group, person) => {
group[person.id] = person;
return group;
}, {});
const result = arr2.map((personPartFromSecondArray) => {
const personPartFromFirstArray = groupedById[personPartFromSecondArray.id];
if (typeof personPartFromFirstArray !== "undefined") {
return { ...personPartFromFirstArray, ...personPartFromSecondArray }
}
return personPartFromSecondArray;
});
console.log(result);

Access and extract values from doubly nested array of objects in JavaScript

I have an array of objects and within those objects is another object which contains a particular property which I want to get the value from and store in a separate array.
How do I access and store the value from the name property from the data structure below:
pokemon:Object
abilities:Array[2]
0:Object
ability:Object
name:"blaze"
1:Object
ability:Object
name:"solar-power"
How would I return and display the values in the name property as a nice string like
blaze, solar-power ?
I tried doing something like this but I still get an array and I don't want to do a 3rd loop since that is not performant.
let pokemonAbilities = [];
let test = pokemon.abilities.map((poke) =>
Object.fromEntries(
Object.entries(poke).map(([a, b]) => [a, Object.values(b)[0]])
)
);
test.map((t) => pokemonAbilities.push(t.ability));
Sample Data:
"pokemon": {
"abilities": [
{
"ability": {
"name": "friend-guard",
"url": "https://pokeapi.co/api/v2/ability/132/"
},
"ability": {
"name": "Solar-flare",
"url": "https://pokeapi.co/api/v2/ability/132/"
}
}
]
}
Then I am doing a join on the returned array from above to get a formatted string.
It just seems like the multiple map() loops can be optimized but I am unsure how to make it more efficient.
Thank you.
There is no need for a loop within loop. Try this:
const pokemon = {
abilities: [{
ability: {
name: 'friend-guard',
url: 'https://pokeapi.co/api/v2/ability/132/'
},
}, {
ability: {
name: 'Solar-flare',
url: 'https://pokeapi.co/api/v2/ability/132/'
}
}]
};
const pokemonAbilities = pokemon.abilities.map(item => item.ability.name).join(', ');
console.log(pokemonAbilities);

Alternative to eval for converting a string to an object

I have a function that is using eval to convert a string with an expression to an object based on the parameter.
let indexType = ["Mac", "User", "Line", "Mask", "Ip", "Location"]
const filterIndex = (item) => {
filteredIndexSearch = []
eval(`search${item}`).forEach((e) => filteredIndexSearch.push(searchData[e.key]))
}
filterIndex(indexType[searchTotal.indexOf(Math.max(...searchTotal))])
searchData is an array that returns values based on the user input.
searchTotal is an array with the length of each search{item} array.
The filterIndex function takes the highest value from the searchData array and corresponds it to the indexType array, then use eval to convert the string to an object to pass the value to the filteredIndexSearch array.
What would be a better alternative to eval?
EDIT
To add more information on what this does:
searchData = [
[
{
key: 1,
data: "0123456789101"
},
{
key: 1,
data: "John Smith"
}
],
[
{
key: 2,
data: "0123456789102"
},
{
key: 2,
data: "Jane Smith"
},
]
]
const search = (data, key, container) => {
if (!data) data = "";
if (data.toLowerCase().includes(string)) {
container = container[container.length] = {
key: key,
data: data
}
}
}
const returnSearch = () => {
for (let i = 0; i < searchData.length; i++) {
search(searchData[i][0].data, searchData[i][0].key, searchMac)
search(searchData[i][1].data, searchData[i][1].key, searchUser)
}
}
returnSearch()
The data is incomplete, but hopefully conveys what I'm trying to do.
search will take the user input, and store the information in the corresponding array. If I input "Jo", it will return the searchUser array with only the "John Smith" value and all the other values with the same key. Inputting "102" returns the searchMac with the "0123456789102" value and all other values with the same key.
At the end of the day. I just want to convert search${parameter} to an object without using eval.
Move your global arrays into an object.
Somewhere it appears that you're defining the arrays, something like:
searchMac = [...];
searchUser = [...];
...
Instead of defining them as individual arrays, I'd define them as properties in an object:
searchIndices.Mac = [...];
searchIndices.User = [...];
...
Then, instead of using eval, your can replace your eval().forEach with searchIndices[item].forEach.
If the order of your search isn't important, your can instead loop through the keys of searchIndices:
Object.keys(searchIndices).forEach(item => {
searchIndices[item].forEach(...);
});
This ensures that if you ever add or drop an entry in searchIndices, you won't miss it or accidentally error out on an undefined search index.
Any time you have a situation with variables named x0, x1 etc, that should be a red flag to tell you you should be using an array instead. Variable names should never be semantically meaningful - that is code should never rely on the name of a variable to determine how the code behaves. Convert search0 etc into an array of search terms. Then use:
const filterIndex = (item) => search[item].map(i => searchData[i.key]);
filteredIndexSearch = filterIndex(indexType[searchTotal.indexOf(Math.max(...searchTotal))]);
(simplifying your code). Note that in your code, filteredIndexSearch is modified inside the arrow function. Better to have it return the result as above.

Javascript: map function appending to an object

I have a map function which is iterating a response i received from backend. I'm iterating the response as 'tab' like the code below, what i want to do is to insert 'tab.name' as an key inside the object MyObject
my code:
var MyObject = {}
response.data.rows.map(tab => {
MyObject = {
...MyObject,
tab.name
}
})
What i expect is that my object MyObject has every keys and values with the name of tab, e.g:
{
name1: name1,
name2: name2,
name3: name3
}
The problem is that i can not use tab.name inside object
You could use collectjs, goes good..
Anyway if you want to have the keys just do a foreach
let response = [
{name: 'name1', age: '22'},
{name: 'name2', age: '25'},
{name: 'name3', age: '2'},
]
var MyObject = {}
response.forEach(tab => {
MyObject[tab.name] = tab.name
})
console.log(MyObject)
If you really want to use .map(), you could use to create an array of arrays, where each sub-array has a length of 2, and holds the given value at each index.
Then you can use Object.fromEntries() to add the properties from that array structure.
var response = {data:{rows:[{name:"foo"}, {name:"bar"}, {name:"baz"}]}};
var key_val_props = response.data.rows.map(({name}) => [name, name]);
var MyObject = Object.fromEntries(key_val_props);
console.log(MyObject);
Theres no need to copy the object just do
MyObject[tab.name] = tab.name;
I'd also avoid using .map since it will be returning the new reference which I dont think that is what you want.

Cannot trim object properties using Javascript or JQuery

I have not been able to find a way to trim (get rid of the white space at the beginning and end of each string) the properties of the array of objects in my code. Following the advice in other threads on here did not work.
I have an array of objects named 'res'. The properties below are in 'res.d'. How can I trim this object and then JSON.parse it as such:
res.d = JSON.parse(res.d)
Thanks
[{"id":"FARM, LODGE","name":"104"},
{"id":"Barn
","name":"124069"},{"id":"Lg\u0027s Barn Fm
","name":"124820"},{"id":"Ld\u0027s Hill Fm
","name":"125103"},{"id
":"Lord\u0027s Wood Fm
","name":"125126"},{"id":"Lo\u0027s Court Fm
","name":"125345"},{"id":"Lo\u0027s Copse ","name":"162"},
{"id"
:"Lodge "}]
You could do something like this:
const items = [
{ id: " LODGE FARM WEST TO LOWER LODGE FARM, LOWER LODGE", name: "10444" },
{ id: "Hello world ", name: "5555" }
];
const res = items.map(item => {
return {
id: item.id.trim(),
name: item.name.trim()
};
});
let newObj = res.d.map((value) => {
return{
id: value.id.trim(),
name: value.name.trim()
}
})
console.log(newObj)
This should trim the values in your object and 'newObj' will have new values
You could also use lodash after requiring it in your code.
If res.d is an array of objects
_.map(res.d, val => _.mapValues(val, _.trim()));
Otherwise if res.d is an object
_.mapValues(res.d, _.trim);
Ref: https://lodash.com/docs/#trim

Categories

Resources