Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 24 days ago.
Improve this question
So basically I have an array of ids and I want to return only a simple array which I want to look like this
*[1,2,3]*
instead of
*[0:[1] , 1:[2]]*
Is there any way to do it
Code
const usersWhoHavePurchasedYourCourses = usersWhoHaveTokens.filter(
(user1: any) => {
return user1.tokens
?.map((token: any) => parseInt(token.course_id))
.includes(user.courses?.map((course: any) => course.id));
});
The output looks like this
output
As I said I don`t want to return this kind of output.
Edit
In attempting to reverse-engineer your logic, wouldn't you want to filter by checking if a user has at least one course? I recommend using Array.prototype.some as your filter result.
const user = { courses: [{ id: 1 }, { id: 2 }] };
const usersWhoHaveTokens = [
{ id: 1, tokens: [{ course_id: '1' }] },
{ id: 2, tokens: [{ course_id: '2' }] },
{ id: 3, tokens: [{ course_id: '3' }] },
];
// Compute the set, for faster processing
const userCourseIds = new Set(user.courses.map((course) => course.id));
const usersWhoHavePurchasedYourCourses = usersWhoHaveTokens
.filter(({ tokens }) => tokens
.some((token) => userCourseIds.has(parseInt(token.course_id))))
.map(({ id }) => id);
console.log(usersWhoHavePurchasedYourCourses); // [1, 2]
Original response
If you object is an 'object' type, you will need to transform it into an array, and then flatten it.
const
obj = { 0: [1], 1: [2] },
arr = Object.values(obj).flat();
console.log(JSON.stringify(arr)); // [1, 2]
If you want to preserve indices:
const
obj = { 1: [2], 5: [6] },
arr = Object.entries(obj).reduce((acc, [index, value]) => {
acc[+index] = value;
return acc;
}, []).map(([value]) => value);
console.log(JSON.stringify(arr)); // [null, 2, null, null, null, 6]
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 months ago.
Improve this question
i have this array
const names = [
{ name: 'Anna' },
{ num: 27 },
{ name: 'Valeria', age: 20},
{ secondname: 'Wilson' },
{ age: 12, name: 'Max' },
{ weight:'50kg', height: '172cm', name: 'Nick' }
]
using reduce i need to create new array that contains all names from initial array
i made like this, but i think it is bad
let allNames = names.reduce((previousValue, names) =>{
return previousValue + names.name},[])
console.log(allNames)
i did
allName.push(ar.name);
return allName;
}, []);
console.log(names);```
Array.reduce()
You have multiple options. You can use Array.reduce to merge them all into one array. You just need to check if name is defined.
names.reduce((allNames, person) => {
if (person.name) {
return [...allNames, person.name];
}
return allNames;
}, []);
Array.forEach()
Same for Array.forEach:
const allNames = [];
names.forEach((person) => {
if (person.name) {
allNames.push(person.name);
}
});
allNames;
Instead, I would recommend using Array.filter to remove all people without a name and map (Array.map) over them, to just return the names.
In terms of runtime, this would require you to loop twice over the array, but I think this is way more readable
Array.filter / Array.map
names
.filter((person) => person.name)
.map((person) => person.name);
Using reduce by including a check for objects that don't have the name property and an empty array as initial value:
const names = [
{ name: 'Anna' },
{ num: 27 },
{ name: 'Valeria', age: 20},
{ secondname: 'Wilson' },
{ age: 12, name: 'Max' },
{ weight:'50kg', height: '172cm', name: 'Nick' }
]
const reduceResult = names.reduce((previous, current) => {
if(current.name)
{
previous.push(current.name);
}
return previous;
}
,
[]);
console.log(reduceResult);
/*
[
"Anna",
"Valeria",
"Max",
"Nick"
]
*/
Using map, you will have undefined for objects that don't have a name property:
const mapResult = names.map(x => x.name);
console.log(mapResult);
/*
[
"Anna",
undefined,
"Valeria",
undefined,
"Max",
"Nick"
]
*/
filter + map can also be used but performance talking reduce is a better choice.
const filterMapResult = names.filter(({name}) => !!name).map(x => x.name);
console.log(filterMapResult);
/*
[
"Anna",
"Valeria",
"Max",
"Nick"
]
*/
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Given an array of objects of products' categories like this:
[{
id: 1,
name: "A",
products: [{
id: 1,
price: 1
}]
},
{
id: 2,
name: "B",
products: [{
id: 2,
price: 1
}]
}
]
please help me with a function that using product's id to return the category name. I've tried but my result always return "A" regardless of which product ID I've input, even the nonexistent one.
This is what I tried so far:
const populate = function(productID) {
// main code here
return categories.find(x => {
let products = x.product;
console.log(products.find(e => e.id = productID));
if (products.find(e => e.id = productID) != undefined) return true;
return false;
}).name;
}
I've looked for anywhere but there are not any answer for my problem.
1) Get the products
(you can use destructuring) and loop over to get the product whose id is equal to productID.
2) There may be a chance you couldn't find the product then you you should handle that case as well. For that, you can use optional chaining
You can also make it one-liner as
const populate = (productID) => categories.find(({ products }) => products.find(({ id }) => id === productID))?.name;
const categories = [
{
id: 1,
name: "A",
products: [
{
id: 1,
price: 1,
},
],
},
{
id: 2,
name: "B",
products: [
{
id: 2,
price: 1,
},
],
},
];
const populate = function (productID) {
return categories.find(({ products }) => {
return products.find(({ id }) => id === productID);
})?.name;
};
console.log(populate(2));
It seems the problem is just a silly typo.
I fixed it by changing
if (products.find(e => e.id = productID) != undefined) return true;
to
if (products.find(e => e.id == productID) != undefined) return true;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Hi I want to delete key in array
here is my array
const data = [ { id: "2" } , { id: "4" } ]
I want ouput
['2','4']
here is what i try
data.map(function(item) {
//I return only item.id but output still not change
return item.id
})
That's because .map() method returns a new array, it does not alternate the current array. You need to store the returned array in another variable to get the required output like:
const data = [ { id: "2" } , { id: "4" } ]
const res = data.map(x => x.id)
console.log( res )
Or, using same variable:
let data = [ { id: "2" } , { id: "4" } ]
data = data.map(x => x.id)
console.log( data )
Map returns new array and do not alter source array. so you need to assign the result to a new variable.
const data = [{
id: "2"
}, {
id: "4"
}];
const output = data.map(function(item) {
return item.id
})
console.log(output)
Something like this? We map the key to a number and return it.
const data = [ { id: "2" } , { id: "4" } ];
var result = Object.keys(data).map(function (key) {
return Number(key);
});
console.log(result);
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
Suppose I have an array of users:
const users =[
{
id:1,
name:'bob',
},
{
id:2,
name:'sally',
},
{
id:3,
name:'bob',
age:30,
}
];
Now I want to extract the keys by either name,id or age(example for name):
const arrangeByName = arrangeBy('name');
arrangeByName(users);
So the result would be:
['bob','sally'];
My arrangeBy function looks like this:
const go = A => key => {
return A.map(a => a.key);
};
export default go;
But when I run this I get:
A.map is not a function
How can I write a function that can extract keys in an array? Also note that any duplicates are not created in the output.
Since you want to exclude objects for which the given key property is not present, and want to exclude duplicates, things become a little more complex.
This solution filters out the objects for which the property is not present, and uses a Set to avoid duplicates:
const arrangeBy = key => A => [...A.reduce((s, v) => key in v ? s.add(v[key]) : s, new Set())];
Complete snippet:
const users = [{
id: 1,
name: 'bob',
}, {
id: 2,
name: 'sally',
}, {
id: 3,
name: 'bob',
age: 30,
}];
const arrangeBy = key => A => [...A.reduce((s, v) => key in v ? s.add(v[key]) : s, new Set())];
const arrangeByName = arrangeBy('name');
const arrangeByAge = arrangeBy('age');
console.log(arrangeByName(users));
console.log(arrangeByAge(users));
I see two issues. One, your arguments are in the wrong order as it seems you want arrangeBy to accept a key and return a function that accepts users. Second, a.key will try to access a property called "key" on the object, which I doubt is what you are trying to do - you will instead want to do a[key]
// get values of key, removing duplicates
const arrangeBy = key => arr =>
[...arr.reduce((set, el) => set.add(el[key]), new Set)]
const arrangeByName = arrangeBy('name')
const arrangeById = arrangeBy('id')
const users = [{id: 1, name: 'bob'}, {id: 2, name: 'sally'}, {id: 3, name: 'bob'}]
console.log(arrangeByName(users))
console.log(arrangeById(users))
You can create Array.prototype.arrangeBy:
Array.prototype.arrangeBy = function(key) {
const array = this
.filter(el => !!el[key])
.map(el => el[key])
return [...new Set(array)]
}
const users = [{
id: 1,
name: 'bob'
}, {
id: 2,
name: 'sally'
},
{
id: 3,
name: 'bob',
age: 30
}
]
console.log(users.arrangeBy('id'))
console.log(users.arrangeBy('name'))
console.log(users.arrangeBy('age'))
function arangeByKey(key) {
return function (arr) {
return arr.map(item => item[key]);
};
}
const arangeByName = arangeByKey('name');
const arrangeById = arangeByKey('id');
console.log(arangeByName(users));
console.log(arrangeById(users));
// If array contains unique element
console.log([... new Set(arangeByName(users))]);
This question already has answers here:
Merge property from an array of objects into another based on property value lodash
(5 answers)
Closed 4 years ago.
I have 2 array of objects
The first one called data:
const data = [
{
id: 1,
nombre: 'Piero',
},
{
id: 4,
nombre: 'Nelson',
},
{
id: 7,
nombre: 'Diego'
},
]
and the second called subs:
const subs = [
{
id: 1,
name: 'Temprano',
},
{
id: 4,
name: 'A tiempo',
},
{
id: 7,
name: 'Tarde'
},
]
In which I want to compare that if they have the same ID, the subs array will pass its name value to it and if it does not match that it puts a '-' in the data array, try this way:
data.forEach((d)=>{
subs.forEach((s)=>{
if(d.id === s.id){
d.subname = s.name;
}
else {
d.subname = '-';
}
});
});
But always assign the values with '-' as if it does not match any. What part am I doing wrong? Is there any other simpler way to do this? I would greatly appreciate your help.
The size of the subs array may vary.
It looks like you are not exiting the inner loop when a successful match is found.
In the first example where you are looking for a match for Piero, in your first iteration 1===1 and d.subname is correctly set to 'Temprano'. However, you then continue to compare the values- 1 !== 4 so Temprano is overwritten with '-', and 1 !== 7 so it is overwritten again.
An alternate approach:
data.forEach(d => {
const match = subs.find(s => s.id === d.id);
d.subname = match ? match.name : '-';});
I'd also recommend adding a case where you're not expecting to find a match, so you can see that it works in both cases!
https://codepen.io/anon/pen/MGGBLP?editors=0010
const data = [
{
id: 1,
nombre: 'Piero',
},
{
id: 4,
nombre: 'Nelson',
},
{
id: 7,
nombre: 'Diego'
},
];
const subs = [
{
id: 1,
name: 'Temprano',
},
{
id: 4,
name: 'A tiempo',
},
{
id: 7,
name: 'Tarde'
},
];
// by caching one of the arrays in an object, it reduces the run time to linear.
const obj = subs.reduce((acc, item) => {
acc[item.id] = item;
return acc;
})
data.forEach(d => {
if (d.id in obj) {
d.subname = obj[d.id].name;
} else {
d.subname = '-';
}
});
console.log(data);
You just need two lines for this:
var findIds = id => subs.find(findId => findId.id === id);
data.forEach(findId => Object.assign(findId, findIds(findId.id)));
Your data array object should now include the name property from it's respective id sharing object in subs array.
jsFiddle: https://jsfiddle.net/AndrewL64/9k1d3oj2/1/