I want to get all name from the array of data. Is there any way to do it without using an iterator?
const data = [
{name: 'Rushabh', age: 22},
{name: 'Bonny', age: 24}
]
console.log(Object.values(data));
Try this:
const data = [
{name: 'Rushabh', age: 22},
{name: 'Bonny', age: 24}
]
const names = data.map(({name}) => name)
console.log(names);
the names will include the list of names.
For getting only a single property, you need to map this property directly.
const
data = [{ name: 'Rushabh', age: 22 }, { name: 'Bonny', age: 24 }],
result = data.map(({ name }) => name); // get only name
console.log(result);
Without some kind of iterator you can not do that. You can use map() with short hand property.
const data = [
{name: 'Rushabh', age: 22},
{name: 'Bonny', age: 24}
]
const name = data.map(({name}) => name);
console.log(name);
Use Array.map() and extract the name property:
const data = [
{name: 'Rushabh', age: 22},
{name: 'Bonny', age: 24}
]
console.log(data.map(x => x.name));
If you are using JQuery, do this:
const data = [
{name: 'Rushabh', age: 22},
{name: 'Bonny', age: 24}
]
var names = $.map( data, function(item, key) { return item.name; } );
// names : ['Rushabh', 'Bonny']
Related
Given the following structure:
const data = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30}],
[{name: 'Chris', age: 16}],
[{name: 'Stewie', age: 1}]
]
}
How can we add to each character the key/value pair of city: 'Quahog' so the output looks as follows:
const item = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30, city: 'Quahog'}], // city added
[{name: 'Chris', age: 16, city: 'Quahog'}], // city added
[{name: 'Stewie', age: 1, city: 'Quahog'}] // city added
]
}
We tried using:
let city = data.characters.[0][0].city;
costs = _.map(items, (itemArray) => {
items = _.map(itemArray, (item) => {
if(!item.city) {
item.city = city;
}
});
But it's not working as intended and we can't get the desired output. Any idea how to accomplish this?
Not sure about the reason for having these single item arrays but this solution will do the work (I'll recommend you take a look at the process that creates this data format which is a little weird)
const data = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30}],
[{name: 'Chris', age: 16}],
[{name: 'Stewie', age: 1}]
]
}
const city = data.characters.find(characters => characters.find(character => character.city))[0].city
const dataWithCities = {
...data,
characters: data.characters.map(characters => characters.map(character => character.city ? character : {...character, city}))
}
console.log(dataWithCities)
Here is another way of doing it with .reduce():
const data = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30}],
[{name: 'Chris', age: 16}],
[{name: 'Stewie', age: 1}]
]
};
data.characters.reduce((a,c)=>
(c[0].city=a[0].city,a));
console.log(data);
When using .reduce() without a second argument it will pick up the first array element as the initial value which is then used as a template to copy the .city property to all the other elements. The actual return value of the .reduce() method is discarded but the input array itself (data) is modified in the process and is then shown in the console.log() expression.
try this one
let city = data.characters.[0][0].city;
let newdata = [];
data.characters.map(items, (itemArray) => {
items = _.map(itemArray, (item) => {
if(item.city === undefined) {
newdata.push({...item , city});
} else {
newdata.push({...item});
}
})
costs = {...newdata}
You can do this without lodash
const data = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30}],
[{name: 'Chris', age: 16}],
[{name: 'Stewie', age: 1}]
]
}
const chars = data.characters.map((x)=>{
return {...x[0] , city : x[0].city ? x[0].city : city}
})
const items = {...data , characters : chars};
const { city } = data.characters.find(([item]) => !!item.city?.length)[0];
const newData = {
...data,
characters: data.characters.map(([char]) => [{ ...char, city }])
};
Summary:
Thanks for reading! I'm stuck trying to figure out how to pass multiple variables (of unknown quantity) into an argument that is taking in an array of objects (of unknown quantity) In short: I want to filter out people that don't match all of the criteria listed from within another array (I'm also open to using rest instead of an array).
Code access:
codePen: (its a mess) https://codepen.io/gold240sx/pen/NWXJKLv?editors=0011
Additional code I found helpful for getting the key value pair: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
For this Question I'm using an existing example from: https://sebhastian.com/javascript-filter-array-multiple-values/ :
let filteredPeople = people.filter(function (currentElement) {
return currentElement.country === "America" && currentElement.age <
25; });
console.log(filteredPeople);
This is awesome except its assuming I already know the params I'm seeking to filter by and the elements I'm seeking to look for associated params.
// Object Arrays:
let people = [
{name: "Steve", age: 27, country: "America"},
{name: "Linda", age: 23, country: "Germany"},
{name: "Jimena", age: 29, country: "Spain"},
{name: "Eric", age: 24, country: "England"},
{name: "Jacob", age: 24, country: "America"},
];
let filters = [
{country: "America"},
{Age: 24}
];
// Function: (Attempt)
const filterMatch = {}
const filterThePeople = ((data, filters) => {
filters.forEach(filter => {
//==========get key and value of filter=====================
for (const [key, value] of Object.entries(filter)) {
filterMatch[key] = value
return {key, value}
}
})
data.forEach(person => {
for (const [key2, value2] of Object.entries(data)) {
return {key2, value2}
}
})
})
console.log(filterThePeople(people, filters))
I'm not sure whether to place the "data.forEach..." statement inside the for statement above... I was thinking of placing an if or switch statement saying to look through the array for each key and when it finds a matching key, then it will look at the value of each and if both keys and values match then += to a list... eventually to return the list to the function. (at least that's the solution I imagine in my head. I'm totally open to any and all alternative ways of accomplishing this!)
Filter People that match every filter.. I might add that the naming of the KEY is very important here. In your example you had Age as a capital later. This also allows you to construct filters like this:
let filters = [ {country: "America", age: 24} ];
let people = [ { name: "Steve", age: 27, country: "America", }, { name: "Linda", age: 23, country: "Germany", }, { name: "Jimena", age: 29, country: "Spain", }, { name: "Eric", age: 24, country: "England", }, { name: "Jacob", age: 24, country: "America", }, ];
let filters = [
{country: "America"},
{age: 24}
];
let results = people.filter(p =>
filters.every(f=> Object.keys(f).every(k => p[k] === f[k]))
)
console.log(results);
You can do something like this
let people = [
{name: "Steve", age: 27, country: "America"},
{name: "Linda", age: 23, country: "Germany"},
{name: "Jimena", age: 29, country: "Spain"},
{name: "Eric", age: 24, country: "England"},
{name: "Jacob", age: 24, country: "America"},
];
let filters = [
{country: "America"},
{age: 24}
];
const filtered = people.filter(p => filters.every(f => {
const [key] = Object.keys(f)
return p[key] === f[key]
}))
console.log(filtered)
How to filter array of objects by property? for example in this array if two or more objects have same properties like name and lastname I want to remove either of them and leave only unique one in an array. example arr:
[ {name: "George", lastname: "GeorgeLast", age: 12},
{name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
result should be either
[ {name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
or
[ {name: "George", lastname: "GeorgeLast", age: 12},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
Apply the technique shown in this answer, which is:
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
...but using findIndex with some criteria rather than just indexOf.
let people = [
{ name: "George", lastname: "GeorgeLast", age: 12 },
{ name: "George", lastname: "GeorgeLast", age: 13 },
{ name: "Bob", lastname: "GeorgeLast", age: 12 }
]
let result = people.filter(
(person, index) => index === people.findIndex(
other => person.name === other.name
&& person.lastname === other.lastname
));
console.log(result);
As for whether it keeps 12-year-old George or 13-year-old George, it is a matter of how findIndex works, which so happens to return the first matching element. So in your example case it will keep 12-year-old George.
The Map object holds key-value pairs and remembers the original insertion order of the keys.
const arr = [
{ name: "George", lastname: "GeorgeLast", age: 12 },
{ name: "George", lastname: "GeorgeLast", age: 13 },
{ name: "Bob", lastname: "GeorgeLast", age: 12 }
];
const newMap = new Map();
arr.forEach((item) => newMap.set(item.name, item));
console.log([...newMap.values()]);
Another solution.
Here you don't need to iterate through the list n*n/2 times (if I count correctly).
On the other hand, this one looks less concise and uses more memory.
Use whichever you prefer.
const arr = [
{name: "George", lastname: "GeorgeLast", age: 12},
{name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}
];
const obj = {}
arr.forEach(v => {
if (!obj[v.name]) {
obj[v.name] = {}
}
if (!obj[v.name][v.lastname]) {
obj[v.name][v.lastname] = v;
}
})
const result = [];
Object.values(obj).forEach(nameObj =>
Object.values(nameObj).forEach(surnObj => result.push(surnObj))
);
console.log(result)
Basically I have this JavaScript array:
const a = [
{name: 'Foo', place: 'US', age: 15},
{name: 'Foo', place: 'UK', age: 21},
{name: 'Bar', place: 'Canada', age: 20},
{name: 'Bar', place: 'China', age: 22}
];
What is the fastest way to make it look like this? (Where the name becomes a single object property in the "a" array). How would I iterate over the array?
const a = [
{
name: 'Foo',
data: [
{
place: 'US', age: 15
},
{
place: 'UK', age: 21
}
]
},
{
name: 'Bar',
data: [
{
place: 'Canada', age: 20
},
{
place: 'China', age: 22
}
]
}
];
Thank you!
You can make use of reduce function to group data based on name property and then take Object.values.
var a = [
{name: 'Foo', place: 'US', age: 15},
{name: 'Foo', place: 'UK', age: 21},
{name: 'Bar', place: 'Canada', age: 20},
{name: 'Bar', place: 'China', age: 22}
];
var result = Object.values(a.reduce((acc, {name, ...rest})=>{
acc[name] = acc[name] || {name, data:[]};
acc[name].data = [...acc[name].data, rest];
return acc;
},{}));
console.log(result);
One way could be to use an ES6 Map. You can use .reduce() to accumulate the objects in a to the Map. Each name can be a key in the map and each value within the map will be an array of objects which have that key as a name. Once you have built the Map, you can use Array.from() to convert the Map to an array, while also providing a mapping function to convert the entries [name, data[]] to objects while the Map to array conversion occurs.
See example below:
const a = [
{name: 'Foo', place: 'US', age: 15},
{name: 'Foo', place: 'UK', age: 21},
{name: 'Bar', place: 'Canada', age: 20},
{name: 'Bar', place: 'China', age: 22}
];
const res = Array.from(a.reduce((m, {name, ...r}) => {
return m.set(name, (m.get(name) || []).concat(r));
}, new Map), ([name, data]) => ({name, data}));
console.log(res);
I have N Arrays. How can I create a generic Map/Zip function that can transpose N number of arrays together. Please see code below for example.
Also, how can i make it work for multidimensional arrays.
Thank you.
// A Arrays
const arrayA1 = [{name: "James"}, {name: "John"}, {name: "Jack"}]
const arrayA2 = [{age: 10}, {age: 20}, {age: 12}]
// B Arrays
const arrayB1 = [{name: "James"}, {name: "John"}, {name: "Jack"}]
const arrayB2 = [{age: 10}, {age: 20}, {age: 12}]
const arrayB3 = [{height: 150}, {height: 200}, {height: 180}]
const result = {}
const result1 = {}
// Transpose A Arrays Only (does not work for B Arrays)------ How can i make the SAME function work for both A and B arrays
arrayA1.map((x, y) => {
let abc = [x, arrayA2[y]];
result1[y] = abc;
result[x.name] = arrayA2[y]
})
console.log(result);
// { James: { age: 10 }, John: { age: 20 }, Jack: { age: 12 } }
// WHICH IS BETTER IMPLEMENTATION >>>>>> result or result1 >> I intend to send to mongodb
console.log(result1);
/*
{ '0': [ { name: 'James' }, { age: 10 } ],
'1': [ { name: 'John' }, { age: 20 } ],
'2': [ { name: 'Jack' }, { age: 12 } ] }
*/
A better result structure would be an array of objects, like
[
{name: xxx, age: yyy},
{name: xxx, age: yyy},
{name: xxx, age: yyy}
]
Here's code to generate it:
// A Arrays
const arrayA1 = [{name: "James"}, {name: "John"}, {name: "Jack"}]
const arrayA2 = [{age: 10}, {age: 20}, {age: 12}]
// B Arrays
const arrayB1 = [{name: "James"}, {name: "John"}, {name: "Jack"}]
const arrayB2 = [{age: 10}, {age: 20}, {age: 12}]
const arrayB3 = [{height: 150}, {height: 200}, {height: 180}]
//
zip = (...arrays) => arrays[0].map((_, n) => arrays.map(a => a[n]));
merge = (x, y) => Object.assign(x, y);
zipMerge = (...arrays) => zip(...arrays).map(props => props.reduce(merge, {}))
//
console.log(zipMerge(arrayA1, arrayA2))
console.log(zipMerge(arrayB1, arrayB2, arrayB3))