How to merge two arrays into one array in angularjs? - javascript

This is my code
$scope.studentDetails=[];
$scope.studentDetails=[0][id:101,name:one]
[1][id:102,name:two]
[2][id:103,name:three]
$scope.studentMarks=[];
$scope.studentMarks=[0][id:101,marks:78]
[1][id:102,marks:89]
i have two arrays,first array contains 2 properties like id and name, second array contains two properties like id and marks,i want to concatinate these two arrays into one array.i want to get output like
$scope.studentDetails=[0][id:101,name:one,marks:78]
[1][id:102,name:two,marks:89]
[2][id:103,name:three,marks:null]

Lodash zip() should do that provided your JavaScript is valid in the first place.
$scope.studentDetails = _.zip($scope.studentDetails, $scope.studentMarks);

I got the answer
var newArray = [];
_.each($scope.studentDetails,function(obj))
{
var data=_.findWhere($scope.studentMarks,{"id":obj.id});
if(!_.isUndefined(data))
{
newArray.push({id:obj.id,name:obj.name,marks:data.marks});
}
else
{
newArray.push({id:obj.id,name:obj.name,marks:"null"});
}
}

Hey you can use the push like
$scope.studentDetails.push({'id':'101','name':'one','marks':'78'});
$scope.studentDetails.push({'id':'102','name':'two','marks':'78'});
$scope.studentDetails.push({'id':'103','name':'three','marks':'78'});
using loop you can append like bellow
for(i = 0; i < studentResult.length; i++){
$scope.studentDetails.push(studentResult[i]);
}

For object array _.zip merged two array into single array where each array element also an array.
You can use .map and .extend to create merged object array with _.zip like
var studentDetails = [{ id: 101, name: 'one' }, { id: 102, name: 'two' }, { id: 103, name: 'three' }];
var studentMarks = [{ id: 101, marks: 78 }, { id: 102, marks: 89 }];
var mergedArray = _.zip(studentDetails, studentMarks); //where each element also an array like [ [{ id: 101, name: 'one' }, { id: 101, marks: 78 }] ]
var studentDetails = _.map(mergedArray, function (item) { return _.extend(item[0], item[1]); }); //[{ id: 101, marks: 78, name: 'one' }, ..]

Related

Convert array to an array object with some modifications

i'm pretty beginner in the JavaScript and I really need help to convert an array to an array object. There are many examples here in stackOverflow, but I need some modidfication during this process, which is why I couldn't do anything
For example I have:
data = [{id: 21, name: "jack"} , {id: 185, name: "yas"}]
and I need to convert it with something like that (id key change to student_id, and present = true, should be added), and the length of this array is dynamic and will change over time.
[
{
"student_id" : 21,
"present" = true
},
{
"student_id" : 185,
"present" = true
}
]
I need to add these array object to:
const data: any = {
here....
};
your help will be much appreciated.
Assuming your data actually looks more like this
data = [{id: 21, name: "jack"}, {id: 185, name: "yas"}]
This is a simple matter of mapping the array to a new format with the properties you want
const data = [{id: 21, name: "jack"}, {id: 185, name: "yas"}]
const newData = data.map(({ id }) => ({
student_id: id,
present: true
}))
console.log(newData)

Compare value and add if matches to an array

Im trying to merge 2 data sources in 1, I wanna loop through them and if a specefic value matches than add it to the first object with the same value and add the in the emty array what is already there. No matter how much objects I have.
So lets say I have this information
Source 1
one = {
"teams": [
{
name: 'ABC',
members: [],
rooms: '0'
},
{
name: 'DEF',
members: [],
rooms: '1'
}
]
}
Source 2
two = {
"persons": [
{
name: 'Foo',
gender: 'male',
room: '1'
},
{
name: 'Bar',
gender: 'female',
room: '2'
}
]
}
And what I want is that the 'persons' array merge to the members array if the 'room and rooms' value matches.
What I would assume is something similar like this:
for(var i = 0 ; i < two.persons.length; i++) {
if (one.teams[i].rooms == two.persons[i].room) {
data.teams[i].members.push(two.persons[i]);
}
}
using higher order methods you can do:
one = {
"teams": [
{
name: 'ABC',
members: [],
rooms: '0'
},
{
name: 'DEF',
members: [],
rooms: '1'
}
]
};
two = {
"persons": [
{
name: 'Foo',
gender: 'male',
room: '1'
},
{
name: 'Bar',
gender: 'female',
room: '2'
}
]
};
var ttt = one.teams.map(function(x){
var roomVal= x.rooms;
x.members = two.persons.filter(function(t){
return t.room == roomVal});
return x;
})
one.teams = ttt;
console.log(one)
The problem with your code is that once you iterate the two array, then you do not go back and see if the previous element matched with the current one.
For example, if [0] on each arrays does not match and you iterate to index [1] in the for-loop, you do not have a way to check if two[1] matched one[0].
To do a complete search, you could directly iterate the arrays for each value of two:
two.persons.forEach(function(person) {
one.teams.forEach(function(team) {
if (team.rooms == person.room) {
team.members.push(person);
}
});
});
There are many strategies to do this. But most important you should iterate each array separately. I would use an Array.forEach();
one.teams.forEach(function (team, teamsIndex, teamsArray) {
two.persons.forEach(function (person, personsIndex, personsArray) {
if (team.room == person.room) {
// Do what you need to do.
}
});
});
Didn't check syntax so be aware to read Array.forEach(); documentation.

I have two arrays, how do I find matchings elements and perform some action? (lodash)

var array1 = [{Age: 24, Name: "Test", StudentID: 101, Checked: false}, {Age:25, Name: "Test", StudentID: 102, Checked: false}];
var array2 = [{ID: 101}];
If any element in array1 has a property of StudentID that is equal to an ID property present in array2 I'd like to set the Checked property in array1 to true.
Any tips? I'd like to do this without writing nested _.each statements.
This is my first take; however, I believe _.some performs an interation anyway.
_.each($scope.array1, function(element1) {
if(_.some($scope.array2, { ID: element1.ID })) {
element1.Checked = true;
}
});
You''ll have to use two loops, since you have two arrays of random length. But you don't have to nest them. Create a map from the array of IDs and then check the index.
var availableIDs = array2.map(function ( item ) { return item.ID; });
array1.forEach(function ( item ) {
if (availableIDs.indexOf(item.StudentID) !== -1) item.Checked = true;
});
Using lodash, use a sequence in which you create a map of items in array1, using _.indexBy(). Create an array of ids from array2 using _.pluck(), and use them with _.at() to get the selected items. Iterate the returned objects using _.forEach() to set the Checked property to true, and .commit() to apply the changes:
function checkById(items, selected) {
_(items) // start chained sequence
.indexBy('StudentID') // create a map of student objects by ids
.at(_.pluck(selected, 'ID')) // create an array of IDs from the objects in the selected array
.forEach(function(item) { // change the items Checked to true
item.Checked = true;
})
.commit(); // executes the chained sequence
}
var array1 = [{
Age: 24,
Name: "Test1",
StudentID: 101,
Checked: false
}, {
Age: 25,
Name: "Test2",
StudentID: 102,
Checked: false
}, {
Age: 22,
Name: "Test3",
StudentID: 103,
Checked: false
}, {
Age: 28,
Name: "Test4",
StudentID: 104,
Checked: false
}];
var array2 = [{
ID: 101
}, {
ID: 104
}];
checkById(array1, array2);
console.table(array1);
document.getElementById('demo').innerText = JSON.stringify(array1, null, ' ');
<script src="https://cdn.jsdelivr.net/lodash/3.10.1/lodash.min.js"></script>
<pre id="demo"></pre>
using a simple mapping function you can compose an easy search through all objects
var array1 = [{Age: 24, Name: "Test", StudentID: 101, Checked: false}, {Age:25, Name: "Test", StudentID: 102, Checked: false}];
var array2 = [{ID: 101}];
function search(studentList,searchQuery) {
var results = [];
studentList.forEach(function(student,sIndex) {
searchQuery.forEach(function(search,qIndex) {
if(search.ID == student.StudentID) {
results.push(student);
}
});
})
return results;
}
search(array1,array2);
what the forEach function does is iterate over each element, passing along the object of the index it's iterating, and the index that object is at.
By having a double nested map it's easy to iterate over the objects and then compare them according to the rules you define.
Then by using a scoped variable you can push matching values into that array, giving you a nice, neat clean result to return.
Now please mind, this is not the most efficient way to handle this. You could do a test which arary is longest and have that one iterate the least time.
So if there are more students than search parameters iterate the students once. If there are more search parameters than students, iterate the search paramateters once.
also you could chooose to 'prefilter" the arrays by sorting them on the index you wish to sort on, skip the ones you don't need by simple min/max exclusion and such.
But you'd be better off using a database query for searching with large quantities of data.
But if you only have a dataset of about a 1000 or so this will suffice.
Try this snippet:
_.each(array1, function (el) {
el.Checked = !!(JSON.stringify(array2).indexOf(el.StudentID) + 1) || el.Checked;
});
Or, you can do without lo-dash.js(with pure JavaScript)
var array1 = [{Age: 24, Name: "Test", StudentID: 101, Checked: false}, {Age:25, Name: "Test", StudentID: 102, Checked: false}];
var array2 = [{ID: 101}];
var students = array1.filter(function(data){
var isTrue = !!(JSON.stringify(array2).indexOf(data.StudentID)+1);
data.Checked = isTrue || data.Checked;
return isTrue;
})
console.log(students)

Divide a Javascript Array and subarrays In 2 arrays

I have this array:
var myArray = [
{ familyName: 'one', subfamilies:
[ { subfamilyName: 'subOne', subItems:
[ { name: 'subOne', code: '1' },
{ name: 'subTwo', code: '2' }
] }
]
},
{ familyName: 'two', subfamilies:
[ { subfamilyName: 'subTwo', subItems:
[ { name: 'subOne', code: '1' },
{ name: 'subTwo', code: '2' },
{ name: 'subTwo', code: '3' }
] }
]
}
]
I need to divide that array in two diferent arrays with the same length if possible (my real array is so much longer), but I am having some problems getting it done. I create 2 blank array and, with for sentence read all the items. First I push the subItems in one blank array, but cannot get the way to create a new subFamily in a blank array variable and then push the sutItems array.
How can be this done?
Thanks a lot in advance.
var myOtherArray = myArray.splice(myArray.length / 2 | 0);

Angularjs - Fetch object in ng-repeat

I have 2 separate json objects coming from the server. Json A below is of a Car model object which is fetch when looking at a car. Json B is meta data which is used throughout the whole application when the web page first loads.
What I need to do is have a lookup on wheel_id while doing a ng-repeat on wheel_handlers so it returns the wheel object from json B and then I can use this within the view and print the results. I think I need to do something with the ng-repeat but I'm not sure to be honest.
A - Car model
[{
id: 14,
name: "Audi",
wheel_handlers: [
{
id: 9,
wheel_id: 62,
arguments: {
amount: 10
}
}
]
}]
B - wheel
{
id: 62,
name: "Change Wheel Size",
arguments: [
{
id: 25,
description: "amount"
}
]
}
I am assuming the following: The Json "A" may include several cars, but also several wheel_handlers (because there is an array at wheel_handler). So the JSON for the cars may also look like this:
[
{
id: 14,
name: "Audi",
wheel_handlers: [
{
id: 9,
wheel_id: 62,
arguments: {
amount: 10
}
},
{
id: 12,
wheel_id: 65,
arguments: {
amount: 12
}
},
{
id: 15,
wheel_id: 30,
arguments: {
amount: 8
}
}
]
},
{
id: 16,
name: "Mercedes",
wheel_handlers: [
{
id: 9,
wheel_id: 62,
arguments: {
amount: 10
}
},
{
id: 12,
wheel_id: 65,
arguments: {
amount: 12
}
}
]
}
]
For the JSON file B I assume that you also meant an Array, which could contain several wheel definitions. As an example:
[
{
id: 62,
name: "Change Wheel Size",
arguments: [
{
id: 25,
description: "amount"
}
]
},
{
id: 65,
name: "test wheel",
arguments: [
{
id: 25,
description: "amount"
}
]
},
{
id: 30,
name: "another wheel",
arguments: [
{
id: 25,
description: "amount"
}
]
}
]
If this is the case, you could iterate over the cars and while iterating call a helper function in the AngularJS controller. You call this helper function and give wheel_handlers of the current car as a parameter. This helper function then checks the wheel_id of each wheel_handler entry and searches these ids in the JSON b file - the wheel definitions. The helper function returns an array containing the wheels, so in the view you may iterate over the wheels. This will use a nested ng-repeat, because at first you iterate over the cars and while iterating over the cars you will iterate over the wheels.
Here is an example of the controller part. I used $scope.cars as the JSON A, and $scope.wheels as JSON B.
var testApp = angular.module('testApp', []);
testApp.controller('testContr', function ($scope) {
$scope.cars = [];
$scope.wheels = [];
$scope.getWheelsByIds = function (wheel_handlers) {
var wheelIds = [];
var returnArray = [];
for (var wheelKey in wheel_handlers) {
wheelIds.push(wheel_handlers[wheelKey].wheel_id);
}
for (var key in $scope.wheels) {
console.log(wheelIds.indexOf($scope.wheels[key].id));
if (wheelIds.indexOf($scope.wheels[key].id) > -1) {
returnArray.push($scope.wheels[key]);
}
}
return returnArray;
}
});
The necessary HTML part could look like this:
<div ng-app="testApp" ng-controller="testContr">
<div ng-repeat="car in cars" ng-init="wheels = getWheelsByIds(car.wheel_handlers)">
<span>Car name: {{car.name}}</span><br/>
<div ng-repeat="wheel in wheels">
<span>Wheel name: {{wheel.name}}</span><br/>
</div>
<br/>
<br/>
</div>
</div>
I create a fiddle demonstration with the test data, view it here: http://jsfiddle.net/4F3YD/10/
You can nest ng-repeats like that, although I'm not sure what you want to achieve
following code will repeat through cars, then wheels in cars and display wheels from object B(wheels) that match the car wheel id, hope that makes sense
<div ng-repeat="car in CarModels">
<div ng-repeat="wheel in car.wheel_handlers">
{{Wheels | filter:wheel.wheel_id}}
</div>
</div>
You can make use of angular filter over here. In the filter function you can check for the id in the second json.
More Documentation on Angular Filter
Code Example:
<div ng-repeat="element in wheel | filterIds:element.id">
And filter Function:
.filter('filterIds', function () {
return function(id) {
$scope.carModel.forEach(function(car){
if(id == car.id)
return id;
});
}
})

Categories