How to get JSON keys and add extra fields? - javascript

I'm trying to get the key of these json objects in order to create a new object with extra filed to create table headers in a React app. JSON data:
let example = [
{
id: 1,
city: 'New York',
},
{
id: 2,
city: 'Paris',
},
]
The function:
getKeys() {
return example.map((key) => {
return {
cityName: key, // gets the whole array
capital: false,
};
});
}
I tries Object.keys( example);, it returns integers; 0, 1.
How can I get the keys in this case? Thanks.

You are trying to map the keys for an array since example is an array. If the data are consistent throughout the array get the first element example[0] and do Object.keys().
So Object.keys(example[0])

There's no need to get the keys if you just want to add a property to the items in the array. I think there's a misunderstanding about .map, which gives you a single item/object in the array, not the keys.
Something like this perhaps?
let example = [{
id: 1,
city: 'New York',
}, {
id: 2,
city: 'Paris',
}];
const modifiedArray = function(arr) {
return arr.map(item => {
return {
id: item.id,
cityName: item.city,
capital: false,
};
})
}
const newArray = modifiedArray (example);
console.log(newArray )

Related

return a value of array that have special name

Im new in react js and I get a problem with my array... I want to return a value of my array that have contain name and adress .and all value are string thi is my data that I need
name :123,
adress:12569
const array = [
0: [ 'name','123' ],
1: [ 'adress','12569'],
2: ['family','4'],
];
You can run loop on the array and assign key-value for each of the array items.
const array = [
['name', '123'],
['adress', '12569'],
['family', '4'],
];
const res = {};
array.forEach((item) => {
res[item[0]] = item[1];
})
console.log(res);
In this case, you should use an Object.
const foo = {
name: '123',
adress: 'bar',
family: '4',
}
So, to access the propertys:
console.log(foo.name); // 123
console.log(foo.adress); // bar
console.log(foo.family); // 4
But if you are getting this information as an array, you can always transform it into an object.
It would make more sense for that data to be combined into a single object rather than a series of nested arrays, and then use find to locate the object that matches the query.
const data = [
{ name: 'Bob', address: '999 Letsbe Avenue', family: 4 },
{ name: 'Sally', address: '8 Treehouse Lane', family: 0 },
{ name: 'Joan', address: '85 Long Terrace', family: 6 }
];
// Accepts the data array, and a query object
function findFamily(data, query) {
// Iterate through the data array to `find`
return data.find(obj => {
// Split the query into key/value pairs
const queryEntries = Object.entries(query);
// And return only those objects where the
// object key/value matches the query key/value
return queryEntries.every(([ key, value ]) => {
return obj[key] === value;
});
// And if there are no matches return 'No match'
}) || 'No match';
}
console.log(findFamily(data, {
name: 'Bob',
address: '999 Letsbe Avenue',
family: 0
}));
console.log(findFamily(data, {
address: '999 Letsbe Avenue',
family: 4
}));
console.log(findFamily(data, {
name: 'Sally'
}));
Additional documentation
every
Destructuring assignment
Object.entries

What is the best approach to clone objects properties when using map()?

I want to add a new property (contactDetails.countryName) and assign a value to a nested object stored in an array called users using the function map().
I've recently learned that I should use the spread operator (...) and then create / assign the new property in order to avoid mutating my original array of objects so I've developed 2 different implementations for this but I'm not really confident I'm following the best practices to accomplish I want to regarding the semantic and performance.
What would be the best approach to accomplish what I want to do in your opinion?
const countries = [
{ id: 3, countryName : "UK" },
{ id: 4, countryName : "Spain" },
{ id: 6, countryName : "Germany"}
];
const users = [
{ id : 1,
name: "Douglas Camp",
dateOfBirth: "23-06-1984",
contactDetails:
{
country: 3,
phone: "7373724997"
}
},
{
id : 2,
name: "Martin Stein",
dateOfBirth: "19-08-1992",
contactDetails:
{
country: 6,
phone: "3334343434"
}
},
];
const usersData = users.map(user=> {
// Version 1 : using spreading operator twice
const newUser = {
...user,
contactDetails: {
...user.contactDetails,
countryName: countries.find(c=> c.id == user.contactDetails.country).countryName
}
};
return newUser;
});
// Version 2: copying the original object property and using spread operator only for cloning the nested object properties
const newUser = {
id: user.id,
name: user.name,
dateOfBirth: user.dateOfBirth,
contactDetails: {
...user.contactDetails,
countryName: countries.find(c=> c.id == user.contactDetails.country).countryName
}
};
console.log(users);
console.log(usersData);
Here is an approach you can consider:
First of all I would Array.reduce the countries to a Map so you can get them via key/value or in this case by countries.get(key) and avoid filtering that array every time.
You can map through the users and for each one create a new object. In this case I call them accounts.
You can also consider using Object.assign
Note that both ... operator and Object.assign are shallow clone approaches. They do not recursively clone the nested objects/children. For that you can use JSON.stringify and JSON.parse etc.
let countries = [
{ id: 3, countryName : "UK" },
{ id: 4, countryName : "Spain" },
{ id: 6, countryName : "Germany"}
].reduce((r,{id, countryName}) => (r.set(id, countryName), r), new Map()) // reduce with Map
let users = [ { id : 1, name: "Douglas Camp", dateOfBirth: "23-06-1984", contactDetails: { country: 3, phone: "7373724997" } }, { id : 2, name: "Martin Stein", dateOfBirth: "19-08-1992", contactDetails: { country: 6, phone: "3334343434" } }, ];
let accounts = users.map(user => Object.assign({}, user, { // <-- map through
contactDetails: {
...user.contactDetails,
countryName: countries.get(user.contactDetails.country) // <-- get by key
}
}))
users[0].id = 2 // <-- modify users
users[0].contactDetails.phone = "00000"
console.log(users, accounts) // <-- no changes to accounts
Notice when we update the users[0].id and users[0].contactDetails.phone the accounts values did not update.
I normally use version 1, the spread operator twice. I also would consider checking out immer which allows you to do mutable updates on a cloned draft and handles merging it back for you.
const newUser = immer(user, draft => {
draft.contactDetails.countryName = countries.find(
c => c.id == user.contactDetails.country).countryName
)
})
Just edit the specific property you want and immer handles copying the rest of it.
Cloning and merging MapsSection
Just like Arrays, Maps can be cloned:
var original = new Map([
[1, 'one']
]);
var clone = new Map(original);
console.log(clone.get(1)); // one
console.log(original === clone); // false. Useful for shallow comparison
I personally like to use Version 1, as it makes your code much less redundant and easier to read. It also passes all the properties of 'user' down to newUser.

how to loop through multiple arrays inside an array and filter a value from it-Javascript

I'm using EXTJS framework for my code.
below is my array structure:
data = [{
id: 22,
rows: [{
id: "673627",
name: "ABS",
address: "536street"
}, {
id: "333",
name: "TEST$$",
address: "536street"
}, {
id: "999",
name: "TEST$$",
address: "536street"
}]
}, {
id: 33,
rows: [{
id: "899",
name: "TES",
address: "536street"
}, {
id: "333",
name: "TEST$$",
address: "536street"
}, {
id: "999",
name: "TES673",
address: "536street"
}]
}]
Now I want to filter the name from this array, whose value I'm comparing with say "TEST$$".
I'm doing this;
Ext.each(data, function(item) {
filter = item.rows.filter(function(name) {
return name.name === "TEST$$";
}, this);
}, this);
console.log(filter);
In this case, it returns only 1 match, where as I have 3 matches for this particular value. It returns the match from the last item in the data array and hence I dont get all the matching values, any idea how this can be looped to get all values matching?
thx!
You're reassigning the filter variable on every iteration over the data array:
filter = item.rows.filter(function(name) {
return name.name === "TEST$$";
}, this);
On the last iteration, there is only one match, the one with id of 333, so that's the only one that you see after running the Ext.each. Try pushing to an external array that doesn't get overwritten instead:
const testItems = [];
Ext.each(data, function(item) {
const filtered = item.rows.filter(row => row.name === "TEST$$")
testItems.push(...filtered);
});
console.log(testItems);
Note that there's no need to pass along the this context.
Another option is to flatMap to extract all rows to a single array first:
const output = data
.flatMap(({ rows }) => rows)
.filter(({ name }) => name === 'TEST$$');

How to create dynamic table headers from JSON in React?

I have a JSON array of objects, I want to create a dynamic table columns/headers based on it in React.
The data:
example = [
{
id: 0,
city: 'New York',
},
{
id: 1,
city: 'Paris',
},
]
I want to iterate through the array, get the key and add extra fields.
So far I have:
columns() {
return Object.keys(Example[0]).map((key) => {
return {
cityName: key,
capital: false,
};
});
}
I get the keys, but they are unordered (random) and the extra field is added to all the objects. I want to get each key to use it as table header (column name) and be able to change capital for each object.
How can I do that in React?
You can use Array.map for this.
example = [
{
id: 0,
city: 'New York',
},
{
id: 1,
city: 'Paris',
},
];
example.map((obj) => {
return {
CITY : obj.city,
ID : obj.id
// Do whatever with the objects
}
})
arr => arr && arr[0] ? object.keys(arr[0]) : [];
make sure all items in array have same keys

json object from javascript nested array

I'm using a nested array with the following structure:
arr[0]["id"] = "example0";
arr[0]["name"] = "name0";
arr[1]["id"] = "example1";
arr[1]["name"] = "name1";
arr[2]["id"] = "example2";
arr[2]["name"] = "name2";
now I'm trying to get a nested Json Object from this array
arr{
{
id: example0,
name: name00,
},
{
id: example1,
name: name01,
},
{
id: example2,
name: name02,
}
}
I tought it would work with JSON.stringify(arr); but it doesen't :(
I would be really happy for a solution.
Thank you!
If you are starting out with an array that looks like this, where each subarray's first element is the id and the second element is the name:
const array = [["example0", "name00"], ["example1", "name01"], ["example2", "name02"]]
You first need to map it to an array of Objects.
const arrayOfObjects = array.map((el) => ({
id: el[0],
name: el[1]
}))
Then you can call JSON.stringify(arrayOfObjects) to get the JSON.
You need to make a valid array:
arr = [
{
id: 'example0',
name: 'name00',
},
{
id: 'example1',
name: 'name01',
},
{
id: 'example2',
name: 'name02',
}
];
console.log(JSON.stringify(arr));
Note that I am assigning the array to a variable here. Also, I use [] to create an array where your original code had {}.

Categories

Resources