I have the following object:
const info = [{ name: 'John', address: 'america', gender: 'Male', job: 'SE' }];
And I need to spread this array object and get this as
form:{
name:"John",
address:"america",
gender:"Male",
job:"SE"
}
How can I do that?
You don't need spread for that unless you want to make a shallow copy of the object. Instead, just use the object that's in the array:
const form = info[0];
or as a property on an object:
const obj = {form: info[0]};
At that point, form/obj.form and info[0] are both pointing to the same object.
If you do want to make a shallow copy, then spread is useful:
const form = {...info[0]};
or
const obj = {form: {...info[0]}};
There, form/obj.form points to a new object that has a copy of info[0]'s properties.
You could destructure the array and take the wanted property as target.
const
info = [{ "name": "John", "address": "america", "gender": "Male", "job": "SE" }],
result = {};
[{ ...result.form }] = info;
console.log(result);
Related
I have a object which has some properties for one user, and I have array of objects which is returned from API.
My goal is to check which object of Array of objects has the same property as the one single initial object, and then it should return only part of it's properities.
I have tried to use .map on Array of objects but it seems not workig.
Below is the code example. I have also prepared codesandbox if You wish.
const user =
{
name: "jan",
lastName: "kowalski",
fullName: "jan kowalski",
car: "audi"
}
;
const usersAnimal = [
{
name: "jan",
lastName: "kowalski",
fullName: "jan kowalski",
animal: "cat",
animalSize: "small",
animalName: "Bat"
},
{
name: "john",
lastName: "smith",
fullName: "john smith",
animal: "dog",
animalSize: "middle",
animalName: "Jerry"
},
{
name: "Anna",
lastName: "Nilsson",
fullName: "Anna Nilsson",
animal: "cow",
animalSize: "big",
animalName: "Dorrie"
}
];
const filtered = usersAnimal.map((userAnimal)=>userAnimal.fullName === user.fullName && return userAnimal.animalName & userAnimal.animalSize & userAnimal.animal);
thanks
https://codesandbox.io/s/admiring-edison-qxff42?file=/src/App.js
For case like this, it would be far easier if you filter it out first then proceed using map:
const filtered = usersAnimal
.filter((animal) => animal.fullName === user.fullName)
.map(({ animalName, animalSize, animal }) => {
return {
animalName,
animalSize,
animal
};
});
I am providing a for loop solution as I haven't learnt many array methods in javascript.
For me the simplest option is to use a for loop and an if check to loop through the arrays values to check for included values.
for (let v in usersAnimal) {
if (usersAnimal[v].fullName === user.fullName) {
console.log(usersAnimal[v])
}
}
The code above will log the entire usersAnimal object containing the fullname we are looking for.
{
name: 'jan',
lastName: 'kowalski',
fullName: 'jan kowalski',
animal: 'cat',
animalSize: 'small',
animalName: 'Bat'
}
commented for further understanding
for (let v in usersAnimal) {
//loops though the array
if (usersAnimal[v].fullName === user.fullName) {
//when the index value 'v' has a fullname that matches the user fullname value
// it passes the if check and logs that object value
return console.log(usersAnimal[v])
//return true...
}
//return null
}
//etc
If you want to filter, I recommend you to use filter.
The map method will create a new array, the content of which is the set of results returned by each element of the original array after the callback function is operated
const user = {name:"jan",lastName:"kowalski",fullName:"jan kowalski",car:"audi"};
const usersAnimal = [{name:"jan",lastName:"kowalski",fullName:"jan kowalski",animal:"cat",animalSize:"small",animalName:"Bat"},{name:"john",lastName:"smith",fullName:"john smith",animal:"dog",animalSize:"middle",animalName:"Jerry"}];
// Get an array of matching objects
let filtered =
usersAnimal.filter(o => o.fullName === user.fullName);
// You get the filtered array, then you can get the required properties
filtered.forEach(o => {
console.log(
'animal:%s, animalSize:%s, animalName:%s',
o?.animal, o?.animalSize, o?.animalName
);
});
// Then use map to process each element
filtered = filtered.map(o => {
const {animal, animalSize, animalName} = o;
return {animal, animalSize, animalName};
});
console.log('filtered', filtered);
I have an object array with object key value.
arr = [obj1:{name:"Jack", surname:"Peralto"}, obj2:{name:"Husnu", surname:"White"}]
I do not want to see obj1 and obj2 labels. Because of these labels I could not use a word template package.
So I want to convert it to this form.
arr = [{name:"Jack", surname:"Peralto"}, {name:"Husnu", surname:"White"}]
.map function does not work at first array.
arr.map(o=>o)
Why I have an array like this? I should use reduce function and obj1 and obj2 labels are key value when I create object array. Now I don't need them.
When you fix the syntax errors in your code ([obj1:{... is not a valid data structure) you can use Object.values to get at the nested objects.
const obj = {
obj1: {
name: "Jack",
surname: "Peralto"
},
obj2: {
name: "Husnu",
surname: "White"
}
};
console.log(Object.values(obj));
its not the right syntax of array you have used array don't have key value pair
use this syntax if you are using object of objects with key value pair
const obj = {
obj1: {
name: "Jack",
surname: "Peralto"
},
obj2: {
name: "Husnu",
surname: "White"
}
};
or use this an array contains object
arr = [
{name:"Jack", surname:"Peralto"},
{name:"Husnu", surname:"White"}
]
I would like to combine elements of 2 arrays based on the name. For example:
Array1 = [
{name: "name1", language: "lang1"},
{name: "name2", language: "lang2"},
{name: "name3", language: "lang3"}]
Array2 = [
{name: "name1", subject: "sub1"},
{name: "name2", subject: "sub2"},
{name: "name3", subject: "sub3"}]
I need to generate the following array:
Array3 = [
{language: "lang1", subject: "sub1"},
{language: "lang2", subject: "sub2"},
{language: "lang3", subject: "sub3"}]
The logic I could think of was to write an explicit for loop to compare every element of first array with every element of second array and check if name matches as shown below.
let Array3 = []
for(let i=0;i<Array1.length;i++)
{
let elem = Array1[i];
for(let j=0;j<Array2.length;j++)
{
if(Array2[j].name===elem.name)
{
Array3.append({language: elem.language, subject: Array2[j].subject})
break;
}
}
}
However, my actual dataset is quite large and this seems inefficient. How can this can be achieved in a more efficient manner (like using higher order functions or something)?
Using a Map for O(1) lookup of one of the arrays using name as key lets you iterate each array only once.
const Array1=[{name:"name1",language:"lang1"},{name:"name2",language:"lang2"},{name:"name3",language:"lang3"}],Array2=[{name:"name1",subject:"sub1"},{name:"name2",subject:"sub2"},{name:"name3",subject:"sub3"}];
const a1Map = new Map(Array1.map(({name, ...r})=> [name, {...r}]));
const res = Array2.map(({name, ...r}) => ({...r, ...a1Map.get(name)}))
console.log(res)
You need to iterate over the two arrays and group the generated object in a map having the name as the key:
let Array1 = [
{name: "name1", language: "lang1"},
{name: "name2", language: "lang2"},
{name: "name3", language: "lang3"}
];
let Array2 = [
{name: "name1", subject: "sub1"},
{name: "name2", subject: "sub2"},
{name: "name3", subject: "sub3"}
];
let map = new Map();
Array1.forEach(e => map.set(e.name, {language: e.language}));
Array2.forEach(e => {
if(map.has(e.name))
map.set(e.name, {...map.get(e.name), subject: e.subject});
});
let Array3 = [...map.values()].filter(e => e.language && e.subject);
console.log(Array3);
Yes you are thinking in right order , you need to use the sort algorithm logics , I will say nested for loops will be just as good. With larger dataset , since you need to extract the values from two different array you can use the nested for loops.
for(int i=0;i>array1.length();i++){
This can be use for first array
Define String x=",";
For second
for(int j=0;j>array2.length();j++)
{
Check if ( (","+j+",").contains(x)) then break;
If array1 name found in array 2, store array3 as you want
Also Store value of j in x
Like x=x +j+",";
}}
This way your nested for loop will skip the comparison code.
Above algo is raw but will reduce the complexity a significant bit.
I found unexpected result when try to merge with lodash object with flat array inside.
Here the example:
var people = { name: 'Andrew', age: '30', values: ["PT", "PORTA 31"] };
const person = { age: '31', values: ["PT"] };
var people2 = { name: 'Andrew', age: '30', values: [{ pippo : 1}] };
const person2 = { age: '31', values: [{ pippo : 2}] };
// Now merge person back into people array
console.log(_.merge({}, people, person));
console.log(_.merge({}, people2, person2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
The result of first console.log is
{
age: "31",
name: "Andrew",
values: ["PT", "PORTA 31"]
}
And not as expected
{
age: "31",
name: "Andrew",
values: ["PT"]
}
Someone can explain me why and give me a solution to make sure that with a flat array it takes me the correct value
I think assign is better in this case than merge
This method is like _.assign except that it recursively merges own and inherited enumerable string keyed properties of source objects into the destination object. Source properties that resolve to undefined are skipped if a destination value exists. Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources.
var people = { name: 'Andrew', age: '30', values: ["PT", "PORTA 31"] };
const person = { age: '31', values: ["PT"] };
console.log(_.assign({}, people, person));
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.20/lodash.min.js"></script>
I believe _.assign(people, person) would produce the desired outcome in this case https://lodash.com/docs/4.17.15#assign
This functionality is also native and can be used like this Object.assign(target, source)
I'm trying to create a new object (newobj) with new keys and props from a poorly structured existing array of object (arrays?) ex.
[{"product":["1009", "name", "price", "image", "description"]},
{"product":["1004", "name2", "price2", "image2", "description2"]}]
I'm getting result I want but newobj does not update outside of the scope of the forEach method (more than 1 result). My question is what am I not getting ? Is forEach incorrect method with this type obj?
var newobj = {};
Object.keys(oldobj).forEach(function(prop) {
newobj["id"] = Number(oldobj[prop]["product"][0]),
newobj["name"] = oldobj[prop]["product"][1],
newobj["price"] = Number(oldobj[prop]["product"][3]),
newobj["image"] = "url" + oldobj[prop]["product"][0] + ".jpg",
newobj["description"] = oldobj[prop]["product"][2];
// this works
// console.log(JSON.stringify(newobj));
});
// this only updated with one
app.locals.newobj = newobj;
I've also tried mapping (w/ underscore) but I have the same result, I can't access outside scope.
_.each(mappedobj, function(prop) {
_.each(prop["product"][0], function(vals){
newobj["id"] = Number(prop["product"][0]);
console.log(JSON.stringify(newobj));
});
});
If you want all the values from the old object, you need to make newobj an array of objects. You can use .map() to do this transformation.
Object and array destructuring is a convenient way to avoid all those hard-coded indexes. And by naming the parameter variables properly, you can use object literal shorthand to create the resulting objects more easily.
var oldobj = [{
"product": ["1009", "name", "price", "image", "description"]
},
{
"product": ["1004", "name2", "price2", "image2", "description2"]
}
];
var newobj = oldobj.map(({product: [id, name, price, url, description]}) =>
({id: Number(id), name, price: Number(price), url: `url${url}.jpg`, description})
);
console.log(newobj);
Try this
let newObject = _.map(oldObject, (item) => {
return {
id: item.product[0],
name: item.product[1],
price: item.product[2],
image: item.product[3],
description: item.product[4]
};
});
If you want to convert an array of poorly structured object to an array of well structured ones, you can use Array.prototype.map from VanillaJS:
const data = [
{"product": ["1009", "name", "120", "image", "description"]},
{"product": ["1004", "name2", "250", "image2", "description2"]},
{"product": ["1012", "name3", "85", "image3", "description3"]}
];
const products = data.map(({ product }) => {
const [id, name, price, image, description] = product;
return {
id: Number(id),
name,
price: Number(price),
image: `url${image}.jpg`,
description
};
});
console.log(products);