How can i sort the list and print in react? - reactjs

How can i sort the data and print in react.
which libraries do i need to use ?
here is the data which is to be sorted field wise
data = [{
key: 1,
name: 'Steve',
city: 'Paris',
}, {
key: 2,
name: 'Tim',
city: 'London',
}, {
key: 3,
name: 'Stella',
city: 'Bankok',
}, {
key: 4,
name: 'John',
city: 'Paris',
}];

Use Array.prototype.sort() for this.
Check this example:
data = [{
key: 1,
name: 'Steve',
city: 'Paris',
}, {
key: 2,
name: 'Tim',
city: 'London',
}, {
key: 3,
name: 'Stella',
city: 'Bankok',
}, {
key: 4,
name: 'John',
city: 'Paris',
}];
data.sort((a,b) => a.name > b.name);
console.log('updated data', data)

Related

Merge two arrays avoiding O(n^2) complexity

Given two arrays, farmers and collections, I want to be able to merge the farmer information to each collection when farmer_id in the collection is equal to id in farmers. if there is no id of the farmer that matches farmer_id in the collection then that collection should have a an empty farmer object
const farmers = [{
id: 10,
name: 'John Doe',
email: 'jdoe#gmail.com'
},
{
id: 11,
name: 'James Bond',
email: 'james#gmail.com'
}
]
const collections = [{
id: 9,
name: 'Book',
farmer_id: 10,
date: 'June'
},
{
id: 10,
name: 'Game',
farmer_id: 11,
date: 'July'
},
{
id: 13,
name: 'Car',
farmer_id: 10,
date: 'August'
},
{
id: 11,
name: 'Wristwatches',
farmer_id: 20,
date: 'August'
}
]
The result should be in this format below
const result = [{
id: 9,
name: 'Book',
farmer_id: 10,
date: 'June',
farmer: {
id: 10,
name: 'John Doe',
email: 'jdoe#gmail.com'
}
},
{
id: 10,
name: 'Game',
farmer_id: 11,
date: 'July',
farmer: {
id: 11,
name: 'James Bond',
email: 'james#gmail.com'
}
},
{
id: 13,
name: 'Car',
farmer_id: 10,
date: 'August',
farmer: {
id: 10,
name: 'John Doe',
email: 'jdoe#gmail.com'
}
},
{
id: 11,
name: 'Wristwatches',
farmer_id: 20,
date: 'August',
farmer: {}
}
]
This is what i have been able to come up with but am stuck right now
function mapper(farmers, collectors) {
for (let k = 0; k < farmers.length; k++) {
const idToFarmerInfo = {};
idToFarmerInfo[farmers[k].id] = farmers[k];
for (let j = 0; j < collectors.length; j++) {
let mapper = idToFarmerInfo[collectors[j].farmer_id];
farmers[mapper] = collectors[j]
}
}
return farmers
}
i followed this link as am trying to avoid O of N squared but O of N complexity
For a better performance you could create a hash of farmers where the complexity is O(N) because we're iterating the farmers list only once.
const farmers = [{ id: 10, name: 'John Doe', email: 'jdoe#gmail.com' }, { id: 11, name: 'James Bond', email: 'james#gmail.com' } ]; const collections = [{ id: 9, name: 'Book', farmer_id: 10, date: 'June' }, { id: 10, name: 'Game', farmer_id: 11, date: 'July' }, { id: 13, name: 'Car', farmer_id: 10, date: 'August' }, { id: 11, name: 'Wristwatches', farmer_id: 20, date: 'August' } ]
var farmers_hash = farmers.reduce((hash, item) => {
hash[item.id] = item;
return hash;
}, {});
console.log(farmers_hash);
The following step is to build the desired output by assigning one farmer using hash keys.
This can be achieved using map method in combination with Object.assign.
const farmers = [{ id: 10, name: 'John Doe', email: 'jdoe#gmail.com' }, { id: 11, name: 'James Bond', email: 'james#gmail.com' } ]; const collections = [{ id: 9, name: 'Book', farmer_id: 10, date: 'June' }, { id: 10, name: 'Game', farmer_id: 11, date: 'July' }, { id: 13, name: 'Car', farmer_id: 10, date: 'August' }, { id: 11, name: 'Wristwatches', farmer_id: 20, date: 'August' } ]
var farmers_hash = farmers.reduce((hash, item) => {
hash[item.id] = item;
return hash;
}, {});
var result = collections.map((item) => {
item.farmer = Object.assign({}, farmers_hash[item.farmer_id])
return item;
});
console.log(result);
As you can see the final complexity is O(N) + O(M) where N is the length of farmers array and M is the length of collections array.
Demo on stackblitz
You can use a more declarative approach and use Array.map and Array.find
const result = collections.map(collection => {
return {
...collection,
farmer: farmers.find(farmer => collection.farmer_id == farmer.id) || {}
};
});
console.log(result);
You can create a Map collection to have O(N) of access to desired farmer by id. Then mapping becomes faster in terms of performance:
const unique = new Map(farmers.map(f=> [f.id, f]));
const result = collections.map(s => ({
...s, farmer_id: unique.get(s.farmer_id) || s.farmer_id
}))
Now mapping of collections has complexity O(N). However, do not forget to sum complexity of making unique farmers. The overall complexity is O(N) + O(M).
An example:
const farmers = [{
id: 10,
name: 'John Doe',
email: 'jdoe#gmail.com'
},
{
id: 11,
name: 'James Bond',
email: 'james#gmail.com'
}
];
const collections = [{
id: 9,
name: 'Book',
farmer_id: 10,
date: 'June'
},
{
id: 10,
name: 'Game',
farmer_id: 11,
date: 'July'
},
{
id: 13,
name: 'Car',
farmer_id: 10,
date: 'August'
},
{
id: 11,
name: 'Wristwatches',
farmer_id: 20,
date: 'August'
}
];
const unique = new Map(farmers.map(f=> [f.id, f]));
const result = collections.map(s => ({
...s, farmer_id: unique.get(s.farmer_id) || s.farmer_id
}))
console.log(result);

Get the sum of 3rd property if first two properties matches

I have three properties in an array. I want the the sum of the 3rd property when the first 2 properties have the same value. My goal is to have an array in which the first two properties are unique.
For the following example
var arrayPeople = [
{
name: 'joe',
category: 'leave',
count: 2,
},
{
name: 'bob',
category: 'travel',
count: 1,
},
{
name: 'joe',
category: 'leave',
count: 1,
},
{
name: 'bob',
category: 'travel',
count: 3,
};
];
I would expect
arrayPeople = [
{
name: 'joe',
category: 'leave',
count: 3,
},
{
name: 'bob',
category: 'travel',
count: 4,
};
];
There is only one occurrence of name: 'joe', category: 'leave' and its count: 3 is the sum of the two counts in the first array.

How to filter all the fields in react?

How to filter all the fields in react?
I have written a code which only filters specified fields.
let filteredContacts=this.props.contacts.filter(
(contact)=>{
return contact.name.indexOf(this.state.search)!==-1;
}
);
the above code only returns filtered names...but i want to filter name,age,city work.
this is the data file:
export default function(){
return [{
key: 1,
name: 'Steve',
city: 'Paris',
}, {
key: 2,
name: 'Tim',
city: 'London',
}, {
key: 3,
name: 'Stella',
city: 'Bankok',
}, {
key: 4,
name: 'John',
city: 'Paris',
}];
}
i want to create a search bar which which filters all the fields suppose if i search john then the list of john should be displayed and if i search paris then all the entries which have paris should be displayed..So the code which i have written only searches for name as i have specified name..i want to search the inputed data to search all the fields.
The filter criteria can be the indexOf on Object.values() like below but it will only give a complete match
var data = [{
key: 1,
name: 'Steve',
city: 'Paris',
}, {
key: 2,
name: 'Tim',
city: 'London',
}, {
key: 3,
name: 'Stella',
city: 'Bankok',
}, {
key: 4,
name: 'John',
city: 'Paris',
}];
var value = 'Paris'
var newData = data.filter((obj) => {
return Object.values(obj).indexOf(value) > -1
})
console.log(newData)
Well, I fastly tried, do a loop on your keys. Maybe there's a more elegant way.
let filteredContacts=this.props.contacts.filter(
(contact)=>{
var found = false;
Object.keys(contact).map(function(key, index) {
if (contact[key].indexOf(this.state.search) >= 0)
found = true;
}
return found;
}
);

Angular show list in alphabetical order and also show divider

**please anyone can help me i want to print list in Angularjs like this **
enter image description here
Use Order by
$scope.friends = [
{name: 'John', phone: '555-1212', age: 10},
{name: 'Mary', phone: '555-9876', age: 19},
{name: 'Mike', phone: '555-4321', age: 21},
{name: 'Adam', phone: '555-5678', age: 35},
{name: 'Julie', phone: '555-8765', age: 29}
];
<tr ng-repeat="friend in friends | orderBy:'name'">
read more here
You have to filter each group by the letters you want. Here's a Plunker Using this list:
$scope.myList = [{
id: 11,
name: 'Okra'
}, {
id: 12,
name: 'Musa'
}, {
id: 4,
name: 'Sky'
}, {
id: 13,
name: 'India'
}, {
id: 14,
name: 'Rose'
}, {
id: 15,
name: 'Titanic'
}, {
id: 16,
name: 'Onion'
}, {
id: 6,
name: 'Germany'
}, {
id: 17,
name: 'Beer'
}, {
id: 18,
name: 'Run'
}, {
id: 2,
name: 'Garden'
}, {
id: 19,
name: 'Mountain'
}]
One function to get the alphabets between the two:
function genCharArray(charA, charZ) {
var a = [], i = charA.charCodeAt(0), j = charZ.charCodeAt(0);
for (; i <= j; ++i) {
a.push(String.fromCharCode(i));
}
return a;
};
Then your filter:
app.filter("cfilter", function () {
return function (input, x, y) {
var groups = [];
var letters = genCharArray(x, y);
for (var i = 0; i < input.length; i++) {
for (var x = 0; x < letters.length; x++) {
if (input[i].name.substring(0, 1) == letters[x])
groups.push(input[i]);
}
} return groups;
}
});
And your HTML:
<div ng-repeat="w in myList | cfilter: 'A':'H' | orderBy: 'name'">
<div>{{w.name}}</div>
</div>
create one directive pass an array of letter and range of alphabates you want to disaply.
<dummy-directive data="arrayData" range="A-G"></dummy-directive>
<dummy-directive data="arrayData" range="H-L></dummy-directive>
<dummy-directive data="arrayData" range="M-P"></dummy-directive>
<dummy-directive data="arrayData" range="Q-Z"></dummy-directive>
Now question is that how to implement directive?
we will display sorted data.

How to edit cells with backgrid

I am trying an example with backgrid paging. I have to edit a cell content on click of edit button then save the updated cell content to the server. Here iam rendering the buttons using backgrid cell extention but not able to figure it out how to enable a cell for editing on click of the button.
Here is the sample am trying.. In EditCell i have a method editRow in which i have to perform the updation.
Thanks
(function(){
//Namespacing the views collections and models
window.App = {
Models: {},
Views: {},
Collections: {},
Helpers: {}
},
//Template helper to load the template of any id
App.Helpers.template = function(id){
return _.template($('#' + id).html());
}
//Person Model
App.Models.Person = Backbone.Model.extend({});
//Person collection - People
App.Collections.People = Backbone.PageableCollection.extend({
model: App.Models.Person,
state: {
pageSize: 10
},
mode: "client"
});
var personCollection = new App.Collections.People([
{
id: 1,
name: 'Trim',
age: 33,
occupation: 'Dotnet Programmer'
},
{
id: 2,
name: 'Crum',
age: 25,
occupation: 'Developer'
},
{
id: 3,
name: 'Drum',
age: 46,
occupation: 'Designer'
},
{
id: 4,
name: 'Srum',
age: 27,
occupation: 'Java Programmer'
},
{
id: 5,
name: 'Vrum',
age: 24,
occupation: 'Developer'
},
{
id: 6,
name: 'Brum',
age: 29,
occupation: 'Designer'
},
{
id: 7,
name: 'Frum',
age: 33,
occupation: 'Dotnet Programmer'
},
{
id: 8,
name: 'Jrum',
age: 25,
occupation: 'Developer'
},
{
id: 9,
name: 'Lrum',
age: 46,
occupation: 'Designer'
},
{
id: 10,
name: 'Hrum',
age: 27,
occupation: 'Java Programmer'
},
{
id: 11,
name: 'Prum',
age: 24,
occupation: 'Developer'
},
{
id: 12,
name: 'Zrum',
age: 29,
occupation: 'Designer'
}
]
);
var EditCell = Backgrid.Cell.extend({
template: _.template('<button>Edit</button>'),
events: {
"click": "editRow"
},
editRow: function (e) {
e.preventDefault();
//Enable the occupation cell for editing
//Save the changes
//Render the changes.
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
this.delegateEvents();
return this;
}
});
var columns = [{
name: "id",
label: "ID",
editable: false,
cell: Backgrid.IntegerCell.extend({
orderSeparator: ''
})
}, {
name: "name",
label: "Name",
cell: "string"
}, {
name: "age",
label: "Age",
cell: "integer"
}, {
name: "occupation",
label: "Occupation",
cell: "string"
}, {
name: "actions",
label: "Actions",
cell: EditCell
}];
// Initialize a new Grid instance
var grid = new Backgrid.Grid({
columns: columns,
collection: personCollection
});
var paginator = new Backgrid.Extension.Paginator({
collection: personCollection
});
// Render the grid and attach the root to your HTML document
$("#grid").append(grid.render().el);
$("#paginator").append(paginator.render().$el);
})();
the following code solved my problem.. With the below code we can make each cell editable/noneditable depending upon a condition. Still looking for a better approach to Enable editing on edit button click.
(function(){
//Person Model
var Person = Backbone.Model.extend({
});
//Person collection - People
var People = Backbone.Collection.extend({
model: Person
});
var personCollection = new People([
{
id: 1,
name: 'Trim',
age: 33,
occupation: 'Dotnet Programmer'
},
{
id: 2,
name: 'Crum',
age: 25,
occupation: 'Developer'
},
{
id: 3,
name: 'Drum',
age: 46,
occupation: 'Designer'
},
{
id: 4,
name: 'Srum',
age: 27,
occupation: 'Java Programmer'
},
{
id: 5,
name: 'Vrum',
age: 24,
occupation: 'Developer'
},
{
id: 6,
name: 'Brum',
age: 29,
occupation: 'Designer'
},
{
id: 7,
name: 'Frum',
age: 33,
occupation: 'Dotnet Programmer'
},
{
id: 8,
name: 'Jrum',
age: 25,
occupation: ''
},
{
id: 9,
name: 'Lrum',
age: 46,
occupation: ''
},
{
id: 10,
name: 'Hrum',
age: 27,
occupation: 'Java Programmer'
},
{
id: 11,
name: 'Prum',
age: 24,
occupation: 'Developer'
},
{
id: 12,
name: 'Zrum',
age: 29,
occupation: 'Designer'
}
]
);
var MyCell = Backgrid.Cell.extend({
initialize: function (options) {
MyCell.__super__.initialize.apply(this, arguments);
this.listenTo(this.model, "backgrid:edited", this.doSomething);
},
doSomething: function () {
console.log('something');
},
enterEditMode: function () {
this.$el.width((this.$el.outerWidth() - 10) + 'px');
Backgrid.Cell.prototype.enterEditMode.apply(this, arguments);
},
exitEditMode: function () {
this.$el.width(false);
Backgrid.Cell.prototype.exitEditMode.apply(this, arguments);
}
});
var columns = [{
name: "id", // The key of the model attribute
label: "ID", // The name to display in the header
editable: false, // By default every cell in a column is editable, but *ID* shouldn't be
// Defines a cell type, and ID is displayed as an integer without the ',' separating 1000s.
cell: "string", //Backgrid.IntegerCell.extend({ tagName: "td style='text-align:left'" })
editable:false,
isEnabled: false
}, {
name: "name",
label: "Name",
// The cell type can be a reference of a Backgrid.Cell subclass, any Backgrid.Cell subclass instances like *id* above, or a string
cell: "string", // This is converted to "StringCell" and a corresponding class in the Backgrid package namespace is looked up
editable:false
}, {
name: "age",
label: "Age",
cell: "string", // An integer cell is a number cell that displays humanized integers
editable: false
}, {
name: "occupation",
label: "Occupation",
cell: MyCell, // A cell type for floating point value, defaults to have a precision 2 decimal numbers
editable: function (c, m) {
if (typeof(c.collection) === 'undefined')
return false;
else
return (c.attributes.age <= 30) ? true : false;
}
}];
// Initialize a new Grid instance
var grid = new Backgrid.Grid({
columns: columns,
collection: personCollection
});
// Initialize a client-side filter to filter on the client
// mode pageable collection's cache.
var filter = new Backgrid.Extension.ClientSideFilter({
collection: personCollection,
fields: ['name']
});
// Render the grid and attach the root to your HTML document
$("#grid").append(grid.render().el);
$("#grid").before(filter.render().el);
})();

Resources