JavaScript - iterating over a specific nested array - javascript

I've searched high and low for this, but can't find examples similar enough to my own. I have virtually no js experience, so I appreciate any help!
Here is my code snippet:
const arr = [];
for (let i = 1; i <= 3; i++) {
arr.push({
name: ["name1","name2","name3"],
data: [0+i,1+i,2+i],
})
}
This is obviously a very simplified version of my use case, but it should be fine for getting an answer.
For all three [arr]'s that are created, I need to increase each value within arr.data by 1. I have no idea how to do this, or if it's even possible.
Edited for sample outputs:
In it's current form, the output will be:
Array [
Object {
name: "name1",
data: Array [1, 2, 3]
},
Object {
name: "name2",
data: Array [2, 3, 4]
},
Object {
name: "name3",
data: Array [3, 4, 5]
}
]
I need the arr.data arrays to add 1 (or any other value) to each item in each data sub-array, so the output would be:
Array [
Object {
name: "name1",
data: Array [2, 3, 4]
},
Object {
name: "name2",
data: Array [3, 4, 5]
},
Object {
name: "name3",
data: Array [4, 5, 6]
}
]
I hope that helps. I'm sure I'm using the wrong terminology for this.
Thanks

Related

How to push array inside array of objects?

I have an array. "branches": [1,2,3,4,5,6,7,8,9,10], I need to push this array into an array of objects. Here multipleBranch is the array of objects. How to achieve this in javascript?
multipleBranch: [
{
branches: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
},
]
The simplest solution as per your description
const branches = [1,2,3,4,5,6,7,8,9,10];
const multipleBranch = [{ branches }];
If you want to add multiple branches then check the code below
const multiBranch = [
{
"branches": [1,2,3,4,5,6,7,8,9,10]
}
]
const addBranch = (arr) => {
multiBranch.push({branches:arr});
}
addBranch([1,2,3]);
console.log(multiBranch);

using array as key to loop through objects in JavaScript

I am learning JavaScript and have spent a good deal of time practicing looping through arrays and arrays of Objects. I wanted to learn how to use an array as a filter on an array of Objects. I couldn't find any articles that explained how to do this, so I had a go myself using a nested loop. However, I cannot get it to work.
Var catKey[]; is the array holding the data I want to use to filter through var posts[]; , identify which objects have a match in the Property cat: [] and return the title properties. I know I could use array.Filter but I want to be able to do this on the assumption I wont always know the number of items in the catKey array. The use case would be for a situation where I use an event handler that when a link I add is clicked on a Post in WordPress and returns the category Ids, I would then search through the list of Posts to find others that have the same category Ids. Can anyone tell me where I am going wrong.
var catKey = [2, 6];
var posts = [
{
id: 1,
cat: [1, 2, 3],
title: "Hello World"
},
{
id: 2,
cat: [5, 6, 7],
title: "Hello JavaScript"
},
{
id: 3,
cat: [8, 9],
title: "Hello Arrays!"
}
];
for (var i = 0; i < catKey.length; i++) {
for (var j = 0; j < posts.length[i]; j++) {
if (catKey[i] === posts[j].cat) {
document.write(posts[j].title);
}
}
}
To find the first entry to match your conditions you can make use of Array.prototype.find() function:
var catKey = [2, 6];
var posts = [
{ id: 1, cat: [1, 2, 3], title: "Hello World" },
{ id: 2, cat: [5, 6, 7], title: "Hello JavaScript" },
{ id: 3, cat: [8, 9], title: "Hello Arrays!" }
];
const resObj = posts
.find(p => p.cat.some(c => catKey.includes(c)))
.title;
console.log(resObj)
Or to find all, use Array.prototype.filter():
var catKey = [2, 6];
var posts = [
{ id: 1, cat: [1, 2, 3], title: "Hello World" },
{ id: 2, cat: [5, 6, 7], title: "Hello JavaScript" },
{ id: 3, cat: [8, 9], title: "Hello Arrays!" }
];
const resObjs = posts
.filter(p => p.cat.some(c => catKey.includes(c)))
.map(o => o.title);
resObjs.forEach((t) => console.log(t));
Based on your question, I assume catKey contains a whitelist of numbers that the nested cat array should match, i.e. as long as any value in the cat array is found in catKeys, you want to keep them.
In that case, you can simply use .filter() to iterate through all the posts, and evaluate if there is any intersection between the individual post's cat array against the whitelist:
var filteredPosts = posts.filter(function(post) {
return post.cat.filter(function(c) { return catKey.indexOf(c) !== -1; }).length;
});
If you want to try and write in ES6, that's also not a problem: and it's even more concise!
const filteredPosts = posts.filter(post => post.cat.filter(c => catKey.includes(c)).length);
See proof-of-concept below:
var catKey = [2, 6];
var posts = [{
id: 1,
cat: [1, 2, 3],
title: "Hello World"
},
{
id: 2,
cat: [5, 6, 7],
title: "Hello JavaScript"
},
{
id: 3,
cat: [8, 9],
title: "Hello Arrays!"
}
];
var filteredPosts = posts.filter(function(post) {
return post.cat.filter(function(c) { return catKey.indexOf(c) !== -1; }).length;
});
console.log(filteredPosts);
You can use map and find together to check the values in the array with the values in the array of objects. Using map the catKey array is iterated and for every element find is used to find that element in the array inside the object inside the array named post using the .includes() method.
var catKey = [2, 6];
var posts = [{
id: 1,
cat: [1, 2, 3],
title: "Hello World"
},
{
id: 2,
cat: [5, 6, 7],
title: "Hello JavaScript"
},
{
id: 3,
cat: [8, 9],
title: "Hello Arrays!"
}];
console.log(catKey.map((e) => posts.find((x) => x.cat.includes(e))))
var catKey = [2, 6];
var posts = [
{
id: 1,
cat: [1, 2, 3],
title: "Hello World"
},
{
id: 2,
cat: [5, 6, 7],
title: "Hello JavaScript"
},
{
id: 3,
cat: [8, 9],
title: "Hello Arrays!"
}
];
var result = posts.filter(({cat})=>{
return catKey.filter((key)=>{
return cat.includes(key)
}).length > 0
})
console.log(result);
short version
posts.filter(({ cat }) => catKey.filter(key => cat.includes(key)).length > 0);

Finding a key in an object by using values from an array

I have an array which is dynamically created by selecting items from a list:
[2, 4]
I also have an array of objects:
[{id: 1, name: "Param1"}, {id: 2, name: "Param2"}, {id: 3, name: "Param3"}, {id: 4, name: "Param4"}]
What I need to do is use the values in the first array to match against the ids in the objects in the second array and return those objects.
Help with this would be much appreciated
Thanks for your time
You can use this ES6 code, which turns the first array to a Set to allow fast lookup, and then applies the Array filter method, specifically intended for this purpose:
var select = [2, 4];
var data = [{id: 1, name: "Param1"}, {id: 2, name: "Param2"},
{id: 3, name: "Param3"}, {id: 4, name: "Param4"}]
var selectSet = new Set(select);
var result = data.filter( obj => selectSet.has(obj.id) );
console.log(result);
You can just use for loop as Liam's comment, or you can use the filter method of array like this:
var keys = [2, 4];
var objs = [{id: 1, name: "Param1"}, {id: 2, name: "Param2"}, {id: 3, name: "Param3"}, {id: 4, name: "Param4"}];
function filterById(obj) {
return keys.indexOf(obj.id) != -1;
}
var newArr = objs.filter(filterById);
The newArr is the result you want.

In Mongo, how would I match all items of collection against a larger array?

Let's say I have 3 items in a collection:
[
{
id: 'a',
items: [1, 2, 3]
}, {
id: 'b',
items: [4, 5, 6]
}, {
id: 'c',
items: [7, 8, 9]
}
]
On the JavaScript code side, all I have is an array [5, 2, 6, 4, 7, 8]. How would I compose my query to select only the 2nd object from the collection since my array has all the elements (4, 5 and 6) of its items array?
Using mongoDB Aggregation Set Operator you can filter your array. First find out intersection of given array with actual database array and after that used set equals method. check below query :
db.collectionName.aggregate({
"$project": {
"checkAllElem": {
"$setEquals": [{
"$setIntersection": ["$items", [5, 2, 6, 4, 7, 8]]
}, "$items"]
},
"items": 1
}
}, {
"$match": {
"checkAllElem": true
}
})

Iterate over a nested object in Javascript and modify some of the items

I have a nested object in Javascript, which I iterate on (with some help from lodash in this case). Simplified like here:
Plunker
$scope.arr = [{
id: 1,
items: [1, 2, 3, 4, 5]
}, {
id: 2,
items: [6, 7, 8, 9, 10]
}, {
id: 3,
items: [11, 12, 13, 14, 15]
}];
_.each($scope.arr, function(node) {
node.id = "item_" + node.id; /* this works fine */
_.each(node.items, function(item) {
item = "item_" + item; /* this does not modify anything */
});
});
Iterating over the first level works fine, probably as the 'node' variable is recognised to belong to the originating array - which is not the case on the second level, there's no binding, like PHP's &$var functionality.
How would you do this? One option is of course to even use the key and something like
node.items[itemKey] = '...';
Is that the only/smartest way?

Categories

Resources