This question already has answers here:
From an array of objects, extract value of a property as array
(24 answers)
Closed 1 year ago.
I currently have an array that has 2 levels. I am attempting to build two new arrays from the initial array but seem to be stuck with the method to use. I have attempted a forEach(), while loop, as well as push to no avail.
My current array structure:
[
{
"attributes": {
"Summary": 10,
"class": "Blue"
}
},
{
"attributes": {
"Summary": 63,
"class":"Red"
}
}
]
I am looking to build two arrays, namely one for summary values, and one for class values.
Are my approaches of a forEach or while loop on the correct path?
If you have an array and want to transform that into another array, the simplest way is to use map (which basically creates a new array containing the results of running each element through a function):
const arr = [
{
"attributes": {
"Summary": 10,
"class": "Blue"
}
},
{
"attributes": {
"Summary": 63,
"class":"Red"
}
}
];
const summaries = arr.map(e => e.attributes.Summary);
const classes = arr.map(e => e.attributes.class);
If you want to accomplish this using forEach, here's one way to do it:
const aryInitial = [
{
"attributes": {
"Summary": 10,
"class": "Blue"
}
},
{
"attributes": {
"Summary": 63,
"class":"Red"
}
}
];
let arySummary = [];
let aryClass = [];
aryInitial.forEach((obj)=>
{
arySummary.push(obj.attributes.Summary);
aryClass.push(obj.attributes.class);
});
console.log("Summary Array:",arySummary);
console.log("Class Array:",aryClass);
Related
I have a question about creating JavaScript arrays. Here's what I want to do.
I have two arrays. Each array has object(s) in them.
The first array has exactly 5 objects, each with a key/value pair (id/name). This array will ALWAYS have 5 objects.
Here's what it looks like...
[
{
"id": 1,
"name": "AnalyticalAdmin"
},
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
},
{
"id": 5,
"name": "SystemAdministrator"
},
{
"id": 6,
"name": "CaseworkSTRTechLeader"
}
]
The second array will have either...
no objects,
4 or less objects,
exactly 5 objects.
In the example below, the second array only has one of the 5 objects in the first array...
[
{
"id": 4,
"name": "AdminReviewer"
}
]
I need to create a third array that has exactly 5 boolean values that are determined by comparing the first two arrays.
For example, based on the first two arrays above, the third array would be...
[false, false, true, false, false]
The reason the third array would look like this is because "AdminReviewer" is the third object in the first array, so the third boolean value in the third array would be true (since it's a match).
But because the first, second, fourth, and fifth objects in the first array do not exist in the second array, their boolean equivalent in the third array would be false.
To accomplish this, I know I need to either do a compare function on the first two arrays to create the third array (of booleans) or I need to run a for loop on the first array, comparing it to the second array to create the third array (of booleans).
Can anyone help me with this?
This could be done as follows:
const filterStrings = filterArray.map(o => JSON.stringify(o));
const result = baseArray.map(o => filterStrings.includes(JSON.stringify(o)));
Please take a look at below runnable code and see how it works.
const baseArray = [
{
"id": 1,
"name": "AnalyticalAdmin"
},
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
},
{
"id": 5,
"name": "SystemAdministrator"
},
{
"id": 6,
"name": "CaseworkSTRTechLeader"
}
];
const filterArray = [
{
"id": 4,
"name": "AdminReviewer"
}
];
const filterStrings = filterArray.map(o => JSON.stringify(o));
const result = baseArray.map(o => filterStrings.includes(JSON.stringify(o)));
console.log(result);
I'm dealing with two objects formatted like this.
{
"MediaListCollection": {
"lists": [
{
"entries": [
{
"mediaId": 121,
"score": 0
},
{
"mediaId": 5114,
"score": 10
}
}
I want to make a new object with all of the entries that appear in both objects (using mediaID as a key). I tried this code but apparently it doesn't work in React because filter is only used on arrays, not objects:
const sameShows = user1Shows.filter(user1Shows.filter(shows1 => user2Shows.some(shows2 => user1Shows.mediaID === user2Shows.mediaID)))
Using Object.entries(user1shows) doesn't fix the problem. I get a [object Array] is not a function error.
I'd like to know if one can use .map() to dynamically change the added value to JS objects.
For example, a static use of .map() allows to add a similar ID to all objects of the array.
friends = [
{
"age": 10,
"name": "Castillo"
},
{
"age": 11,
"name": "Daugherty"
},
{
"age": 12,
"name": "Travis"
}
]
// Static mapping --> adds 1 to all objects
friends_static=friends;
friends.map(elem => elem["id"] = 1);
console.log(friends_static)
This returns [{age=10, name="Castillo", id=1}, {age=11, name="Daugherty", id=1}, {age=12, name="Travis", id=1}]
Is it possible to add a unique ID which increments by 1 for each object in a similar way?
Cf. the illustrative JSfiddle and example code below. I know the 1++ is not legal, but just shows the idea I'm trying to realize.
//Dynamic mapping? --> should add 1,2,3...to objects incrementally
/*
friends_dynamic=friends;
friends.map(elem => elem["id"] = 1++);
console.log(friends_dynamic)
*/
This should return [{age=10, name="Castillo", id=1}, {age=11, name="Daugherty", id=2}, {age=12, name="Travis", id=3}]
You could just use the index provided to the Array#map callback:
friends.map((friend, index) => Object.assign({}, friend, { id: index + 1 }))
It's not a good idea to mutate objects in Array#map. The whole purpose of the method is to return new objects that are mapped from the original objects. Thus use Object.assign to avoid mutation.
Of course, if you wanted mutation, thus just use forEach without mapping to new values. It would be more "semantically correct" in that case.
Is this what you mean?
const friends = [
{
"age": 10,
"name": "Castillo"
},
{
"age": 11,
"name": "Daugherty"
},
{
"age": 12,
"name": "Travis"
}
]
friends.forEach((friend, index) => friend.id = index + 1);
console.log(friends)
if you only need an incremental value from 0 on, you can simply use a counter and increment it, like this:
let id = 1;
friends.map(elem => {elem.id = id++;});
Use a local variable and increment it. As per method definition
"The map() method calls the provided function once for each element in an array, in order". In Order would make sure that ids do not collide.
friends = [
{
"age": 10,
"name": "Castillo"
},
{
"age": 11,
"name": "Daugherty"
},
{
"age": 12,
"name": "Travis"
}
]
// Static mapping --> adds 1 to all objects
friends_static=friends;
var i = 1;
friends_static.map(elem => elem["id"] = i++);
console.log(friends_static)
//Dynamic mapping? --> should add 1,2,3...to objects incrementally
/*
friends_dynamic=friends;
friends_dynamic.map(elem => elem["id"] = 1++);
console.log(friends_dynamic)
*/
Is there any way to compare two arrays and push to an empty array if the condition is met?
Say I have an array of objects. I need to loop through the array of objects, get a ID; then compare that ID to a different array. Then if they match push a value in that array to an empty array?
Array 1:
[{
"addon_service": {
"id": "f6f28cb5-78ad-4ec7-896d-16462b8202fd",
"name": "papertrail"
},
"app": {
"id": "199a1f26-b8e2-43f6-9bab-6e7a6c685ec2",
"name": "mdda-mobiledocdelivery-stg"
}
}]
Array 2
[{
"app": {
"id": "199a1f26-b8e2-43f6-9bab-6e7a6c685ec2"
},
"stage": "staging",
}]
I need to match Array 1 app.ID to Array 2 app.id. If they match check what stage the app is in (staging, development or production). Then push Array 1 addon_service.name to either a staging develpment or
production array depending on what stage the application is in. I'm thinking its simple just cant get my head around it.
I think this is a poorly worded question.
You could use a hash table for lookup and for the stage and use an object for collecting the matches.
var array1 = [{ "addon_service": { "id": "f6f28cb5-78ad-4ec7-896d-16462b8202fd", "name": "papertrail" }, "app": { "id": "199a1f26-b8e2-43f6-9bab-6e7a6c685ec2", "name": "mdda-mobiledocdelivery-stg" } }],
array2 = [{ "app": { "id": "199a1f26-b8e2-43f6-9bab-6e7a6c685ec2" }, "stage": "staging", }],
hash = Object.create(null),
result = {};
array2.forEach(function (a) {
hash[a.app.id] = a.stage;
});
array1.forEach(function (a) {
if (hash[a.app.id]) {
result[hash[a.app.id]] = result[hash[a.app.id]] || [];
result[hash[a.app.id]].push(a.addon_service.name);
}
})
console.log(result);
I think this will do it.
$.each(app1, function(key, value){
$.each(app2, function(k, v){
if(value.app.id == v.app.id){// find apps with the same `id`
if(v[v.stage]){// check if the `stage` array already exists.
v[v.stage].push(value.addon_service)
}else{
v[v.stage] = [value.addon_service];
}
}
});
});
Where app1 is the first array in your question and app2 the second one.
I have 2 array objects in Angular JS that I wish to merge (overlap/combine) the matching ones.
For example, the Array 1 is like this:
[
{"id":1,"name":"Adam"},
{"id":2,"name":"Smith"},
{"id":3,"name":"Eve"},
{"id":4,"name":"Gary"},
]
Array 2 is like this:
[
{"id":1,"name":"Adam", "checked":true},
{"id":3,"name":"Eve", "checked":true},
]
I want the resulting array after merging to become this:
[
{"id":1,"name":"Adam", "checked":true},
{"id":2,"name":"Smith"},
{"id":3,"name":"Eve", "checked":true},
{"id":4,"name":"Gary"},
]
Is that possible? I have tried angular's array_merge and array_extend like this:
angular.merge([], $scope.array1, $scope.array2);
angular.extend([], $scope.array1, $scope.array2);
But the above method overlap the first 2 objects in array and doesn't merge them based on matching data. Is having a foreach loop the only solution for this?
Can someone guide me here please?
Not sure if this find of merge is supported by AngularJS. I've made a snippet which does exactly the same:
function merge(array1, array2) {
var ids = [];
var merge_obj = [];
array1.map(function(ele) {
if (!(ids.indexOf(ele.id) > -1)) {
ids.push(ele.id);
merge_obj.push(ele);
}
});
array2.map(function(ele) {
var index = ids.indexOf(ele.id);
if (!( index > -1)) {
ids.push(ele.id);
merge_obj.push(ele);
}else{
merge_obj[index] = ele;
}
});
console.log(merge_obj);
}
var array1 = [{
"id": 1,
"name": "Adam"
}, {
"id": 2,
"name": "Smith"
}, {
"id": 3,
"name": "Eve"
}, {
"id": 4,
"name": "Gary"
}, ]
var array2 = [{
"id": 1,
"name": "Adam",
"checked": true
}, {
"id": 3,
"name": "Eve",
"checked": true
}, ];
merge(array1, array2);
Genuinely, extend in Angular works with object instead of array. But we can do small trick in your case. Here is another solution.
// a1, a2 is your arrays
// This is to convert array to object with key is id and value is the array item itself
var a1_ = a1.reduce(function(obj, value) {
obj[value.id] = value;
return obj;
}, {});
var a2_ = a2.reduce(function(obj, value) {
obj[value.id] = value;
return obj;
}, {});
// Then use extend with those two converted objects
var result = angular.extend([], a1_, a2_).splice(1)
Notes:
For compatibility, reduce may not work.
The after array will replace the previous one. This is because of implementation of extend in Angular.