Javascript Object Array Sorting Issue - javascript

I have a JavaScript array of objects to sort and arrange it as a new object array preserving the order.
My array of objects. I get them ordered in the way that I want. The index of the objects are 0,1 & 2 in this.
[{0: {name: 'Joel', age:25, id: 2}}, {1: {name: 'Sam', age: 23, id: 4}}, {2: {name: 'Tim', age:27, id: 3}}]
What I want is to make 'id' the index value. And I want it in ascending order of the 'name' (Preserving the above order)
[{2: {name: 'Joel', age:25, id: 2}}, {4: {name: 'Sam', age: 23, id: 4}}, {3: {name: 'Tim', age:27, id: 3}}]
I tried using this function.
for (i in members) {
member[members[i].id] = members[i];
}
But it failed. The output was
[{}, {}, {name: "Joel", age:25, id: 2}, {name: "Tim", age:27, id: 3}, {name: "Sam", age: 23, id: 4}]
I tried using forEach and sort methods too. But all failed.
Is there any way to accomplish this in JavaScript.

You can do it with help of map and sort.
let obj = [{0: {name: 'Joel', age:25, id: 2}}, {1: {name: 'Sam', age: 23, id: 4}}, {2: {name: 'Tim', age:27, id: 3}}]
let op = obj.map((e,index)=>{
return{
[e[index].id] : e[index]
}
}).sort((a,b)=> Object.keys(a) - Object.keys(b))
console.log(op)

Related

Get items in a multidimensional array-like object

I have the following variable:
> let location = {0: {1: {name: 'Fred', age: 20}, 5: {name: 'Ema', age: 55}}, 9: {3: {name: 'John', age: 29}}};
And I want to get the items in it:
> console.log(get_items(location));
[{name: 'Fred', age: 20}, {name: 'Ema', age: 55}, {name: 'John', age: 29}]
I've written the following function:
function get_items(location) {
return _.values(location).reduce((items, item)=> items.concat(_.values(item)), []);
}
But I wonder if there is a more elegant solution for this problem.
You could do this with Array#flatMap and Object#values
The Object#values will extract the value(s) of the outer object:
The Array#flatMap would map and flatten the nested objects into a single array of objects after extracting the value by applying the Object#values again for each object:
let data = {0: {1: {name: 'Fred', age: 20}, 5: {name: 'Ema', age: 55}}, 9: {3: {name: 'John', age: 29}}};
const transform = (data) => Object.values(data).flatMap(Object.values);
console.log(transform(data));

Move repeating object property into a single property in array of objects

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);

Lodash, taking objects fulfilling requirements

Example:
Animals = [{Name: 'Dog', Id: 0},
{Name: 'Cat', Id: 1},
{Name: 'Mouse', Id: null}]
How to take all objects where Id isn't null into new array?
Expected output:
NewArray = [{Name: 'Dog', Id: 0},
{Name: 'Cat', Id: 1}]
Try with _.filter
var Animals = [{Name: 'Dog', Id: 0},{Name: 'Cat', Id: 1},{Name: 'Mouse', Id:null}]
var newArray =_.filter(Animals ,a=> a.Id != null)
console.log(newArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.min.js"></script>

Group an array of objects in AngularJS

Based on an array looking like this:
var members = [
{name: "john", team: 1},
{name: "kevin", team: 1},
{name: "rob", team: 2},
{name: "matt", team: 2},
{name: "clint", team: 3},
{name: "will", team: 3}
];
I need to create an unordered list for each team.
Can it be done directly with ngRepeat and a filter maybe?
Or is it easier to reorganize the array into an array of teams with a list of members?
var teams = [
{id: 1, members: ["john", "kevin"]},
{id: 2, members: ["rob", "matt"]},
{id: 3, members: ["clint", "will"]}
]
The nested ngRepeat would be easy to implement, but how do I go from the first array to this one in a simple / clever manner?
Note: The array doesn't come from the database but from an html table. So it's just a flat list of members.
function MyController() {
this.members = [
{name: "john", team: 1},
{name: "kevin", team: 1},
{name: "rob", team: 2},
{name: "matt", team: 2},
{name: "clint", team: 3},
{name: "will", team: 3}
];
}
angular.module('app', []);
angular.module('app')
.controller('MyController', MyController);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MyController as ctrl">
<ul>
<li ng-repeat="member in ctrl.members">{{ member.name }} - {{ member.team }}</li>
</ul>
</div>
</div>
You have to group items. For this, I used reduce method in order to create
a hash collection which looks like this:
{
"1": [
"john",
"kevin"
],
"2": [
"rob",
"matt"
],
"3": [
"clint",
"will"
]
}
The reduce() method applies a function against an accumulator and each
element in the array (from left to right) to reduce it to a single
value.
The following step is to map this collection in an array. For this, you should use map method.
The map() method creates a new array with the results of calling a
provided function on every element in this array.
var members = [
{name: "john", team: 1},
{name: "kevin", team: 1},
{name: "rob", team: 2},
{name: "matt", team: 2},
{name: "clint", team: 3},
{name: "will", team: 3}
];
var groups = members.reduce(function(obj,item){
obj[item.team] = obj[item.team] || [];
obj[item.team].push(item.name);
return obj;
}, {});
var myArray = Object.keys(groups).map(function(key){
return {team: key, name: groups[key]};
});
console.log(myArray);
Expanding over the #Alexandru-Ionut Mihai's answer, (just to experience how powerful a reduce function is).. here's a single reduce without having to map it again to achieve the same thing. :)
var members = [
{name: "john", team: 1},
{name: "kevin", team: 1},
{name: "rob", team: 2},
{name: "matt", team: 2},
{name: "clint", team: 3},
{name: "will", team: 3}
];
/*var teams = [
{id: 1, members: ["john", "kevin"]},
{id: 2, members: ["rob", "matt"]},
{id: 3, members: ["clint", "will"]}
]*/
var group_to_values = members.reduce(function(arr, item){
arr[item.team - 1] = arr[item.team - 1] || { id: item.team, members: []};
arr[item.team - 1].members.push(item.name);
return arr;
}, []);
console.log(group_to_values);
If you are using underscore.js, then you can use _.groupBy() method to group array of records on the basis of team.
function MyController() {
this.members = [
{name: "john", team: 1},
{name: "kevin", team: 1},
{name: "rob", team: 2},
{name: "matt", team: 2},
{name: "clint", team: 3},
{name: "will", team: 3}
];
var grouped = _.groupBy(this.members, function(member) {
return member.team;
});
}
You can use a groupBy filter like this
<ul ng-repeat="(key, value) in members | orderBy: 'team' | groupBy:ourGrouper">
<li>{{key}}
<ul>
<li ng-repeat="mem in value | orderBy: 'name'">
{{mem.name}}
</li>
</ul>
</li>
</ul>
See this FIDDLE
var members = [
{name: "john", team: 1},
{name: "kevin", team: 1},
{name: "rob", team: 2},
{name: "matt", team: 2},
{name: "clint", team: 3},
{name: "will", team: 3}
];
var groups = members.reduce(function(obj,item){
obj[item.team] = obj[item.team] || [];
obj[item.team].push(item.name);
return obj;
}, {});
var myArray = Object.keys(groups).map(function(key){
return {team: key, name: groups[key]};
});
console.log(myArray);

How to populate an array in enyo.js?

I have an array. I want to give the value of the array in enyo.js.
How will I populate the array dynamically?
Following is the code:
enyo.kind({
name: "enyo.sample.RepeaterSample",
classes: "enyo-fit repeater-sample",
components: [
{kind: "Repeater", onSetupItem:"setupItem", components: [
{name:"item", classes:"repeater-sample-item", components: [
{tag:"span", name: "personNumber"},
{tag:"span", name: "personName"}
]}
]}
],
create: function() {
this.inherited(arguments);
this.$.repeater.setCount(this.people.length);
},
setupItem: function(inSender, inEvent) {
var index = inEvent.index;
var item = inEvent.item;
var person = this.people[index];
item.$.personNumber.setContent((index+1) + ". ");
item.$.personName.setContent(person.name);
item.$.personName.applyStyle("color", person.sex == "male" ? "dodgerblue" : "deeppink");
},
people: [
{name: "Andrew", sex:"male"},
{name: "Betty", sex:"female"},
{name: "Christopher", sex:"male"},
{name: "Donna", sex:"female"},
{name: "Ephraim", sex:"male"},
{name: "Frankie", sex:"male"},
{name: "Gerald", sex:"male"},
{name: "Heather", sex:"female"},
{name: "Ingred", sex:"female"},
{name: "Jack", sex:"male"},
{name: "Kevin", sex:"male"},
{name: "Lucy", sex:"female"},
{name: "Matthew", sex:"male"},
{name: "Noreen", sex:"female"},
{name: "Oscar", sex:"male"},
{name: "Pedro", sex:"male"},
{name: "Quentin", sex:"male"},
{name: "Ralph", sex:"male"},
{name: "Steven", sex:"male"},
{name: "Tracy", sex:"female"},
{name: "Uma", sex:"female"},
{name: "Victor", sex:"male"},
{name: "Wendy", sex:"female"},
{name: "Xin", sex:"male"},
{name: "Yulia", sex:"female"},
{name: "Zoltan"},
]
});
In this case the people is hard coded.
I want to give my value that m getting from json dynamically.
Please help. Thanks.
When you get the array of JSON, then you just set this.people = [data from JSON]. That works if the code is contained in the same top-level kind (enyo.sample.RepeaterSample).
If the JSON return is in a different kind, then you probably need to set a published property for enyo.sample.RepeaterSample thusly:
published: {
people: []
}
And then you can use setPeople(arrayOfPeople). You can also then automatically re-build the repeater in a peopleChanged method:
peopleChanged: function() {
this.$.repeater.setCount(this.people.length);
}

Categories

Resources