Javascript sort data from multiple level of array? - javascript

I have a list which I want sort according to Arrival Date & Departure Date based on Caption and Value. But Arrival and Departure don't exist together in the list. If sort using arrival, then the departure can be ignored, just push to the bottom of the list, and vice versa. How can I achieve that?
var svehicleList = [
{
Brand: 'Volvo',
Summary: [
{
Caption: "Consignee",
Value: "ONE TO ONE SDN BHD",
},
{
Caption: "Arrival",
Value: "18-08-2020 06:01",
}
]
},
{
Brand: 'BMW',
Summary: [
{
Caption: "Consignee",
Value: "ABC SDN BHD",
},
{
Caption: "Arrival",
Value: "14-08-2020 16:03",
}
]
},
{
Brand: 'TOYOTA',
Summary: [
{
Caption: "Consignee",
Value: "MATTA SDN BHD",
},
{
Caption: "Departure",
Value: "14-08-2020 16:03",
}
]
},
{
Brand: 'FERRARI',
Summary: [
{
Caption: "Consignee",
Value: "GLOBAL P SDN BHD",
},
{
Caption: "Departure",
Value: "14-08-2020 18:03",
}
]
},
{
Brand: 'HONDA',
Summary: [
{
Caption: "Consignee",
Value: "HH SDN BHD",
},
{
Caption: "Arrival",
Value: "09-09-2020 16:03",
}
]
},
];
Edited: There is actually two object in summary.

This one helped me: How to Sort Multi-dimensional Array by Value?
You have to write your own comparision function.

You could find the object with the wanted Caption, then sort by occurence and then by date with a wrapper for getting an ISO date.
const
getISO = (string = '') => string.replace(/^(..)-(..)-(....) (.*$)/, '$3-$2-$1 $4'),
sortBy = caption => ({ Summary: a }, { Summary: b }) => {
const
aa = a.find(o => o.Caption === caption),
bb = b.find(o => o.Caption === caption);
return !aa - !bb
|| getISO(aa?.Value).localeCompare(getISO(bb?.Value));
},
vehicleList = [{ Brand: 'Volvo', Summary: [{ Caption: "Consignee", Value: "ONE TO ONE SDN BHD" }, { Caption: "Arrival", Value: "18-08-2020 06:01" }] }, { Brand: 'BMW', Summary: [{ Caption: "Consignee", Value: "ABC SDN BHD" }, { Caption: "Arrival", Value: "14-08-2020 16:03" }] }, { Brand: 'TOYOTA', Summary: [{ Caption: "Consignee", Value: "MATTA SDN BHD" }, { Caption: "Departure", Value: "14-08-2020 16:03" }] }, { Brand: 'FERRARI', Summary: [{ Caption: "Consignee", Value: "GLOBAL P SDN BHD" }, { Caption: "Departure", Value: "14-08-2020 18:03" }] }, { Brand: 'HONDA', Summary: [{ Caption: "Consignee", Value: "HH SDN BHD" }, { Caption: "Arrival", Value: "09-09-2020 16:03" }] }];
vehicleList.sort(sortBy('Arrival'));
console.log(vehicleList);
vehicleList.sort(sortBy('Departure'));
console.log(vehicleList);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

Passing 2 fields to key in headers, react-csv

Related to the existing question. How to assign two fields data in header of react-csv. I am working on something and came across the same issue. Asking again since there is no correct answer given. The following code for headers. - key: "user.firstname + user.lastname" doesn't work and the fields are empty. Please help how to get this working! TIA!!
Code:
headers = [
{
label: "id",
key: "user.id"
},
{
label: "Agent Name",
key: "user.firstName + user.lastName"
},
{
label: "Agent Email",
key: "user.email"
},
{
label: "Agent Phone",
key: "user.phoneNumber"
},
{
label: "Agent Commission",
key: "agentComission"
},
{
label: "Company Commission",
key: "companyComission"
},
{
label: "Total Sale",
key: "sale"
}
];
Data format example :
data = [
{
id: 1,
firstnamename: "name ",
lastname: "lastname",
email: "test#gmail.com",
phoneNumber: 123456789,
agentComission: 'agent comission',
companyComission: 'company comission',
sale: 'sale',
},
{
id: 2,
firstnamename: "name",
lastname: "lastname,
email: "test2#gmail.com",
phoneNumber: 123456789,
agentComission: 'agent comission 2',
companyComission: 'company comission 2',
sale: 'sale 2',
},
];

Comparing two arrays - removing element from array based on object keys

I have two objects.
const arrayOne = [
{
label: "Categories",
to: "/categories",
id: "product_type",
},
{
label: "Colors",
to: "/colors",
id: "color",
},
{
label: "Materials",
to: "/materials",
id: "material",
},
{
label: "Sizes",
to: "/sizes",
id: "sizes",
},
{
label: "Designers",
to: "/designers",
id: "designer_slug",
},
{
label: "Stores",
to: "/stores",
id: "retailer_slug",
},
];
const arrayTwo = [
{
id: "gender",
label: "Gender",
lazy_loaded: false,
},
{
id: "product_type",
label: "Category",
lazy_loaded: false,
},
{
id: "quick_filters",
label: "Quick filters",
lazy_loaded: false,
},
{
id: "final_price",
label: "Price",
lazy_loaded: false,
},
{
id: "color",
label: "Color",
lazy_loaded: false,
},
{
id: "material",
label: "Material",
lazy_loaded: false,
},
{
id: "designer_slug",
label: "Brand",
lazy_loaded: true,
},
{
id: "retailer_slug",
label: "Store",
lazy_loaded: true,
},
];
As you can see they both have the key 'id'. If the IDs in arrayOne aren't in arrayTwo, I would like them to be removed from arrayOne (the whole object). So in this case, only the object with "sizes" should be removed from arrayOne. How would I go about doing this? Thanks in advance!
you could utilize filter:
const newArrayOne = arrayOne.filter(x => arrayTwo.find(y => y.id === x.id))
You could use a Set with id and filter the other array.
const
arrayOne = [{ label: "Categories", to: "/categories", id: "product_type" }, { label: "Colors", to: "/colors", id: "color" }, { label: "Materials", to: "/materials", id: "material" }, { label: "Sizes", to: "/sizes", id: "sizes" }, { label: "Designers", to: "/designers", id: "designer_slug" }, { label: "Stores", to: "/stores", id: "retailer_slug" }],
arrayTwo = [{ id: "gender", label: "Gender", lazy_loaded: false }, { id: "product_type", label: "Category", lazy_loaded: false }, { id: "quick_filters", label: "Quick filters", lazy_loaded: false }, { id: "final_price", label: "Price", lazy_loaded: false }, { id: "color", label: "Color", lazy_loaded: false }, { id: "material", label: "Material", lazy_loaded: false }, { id: "designer_slug", label: "Brand", lazy_loaded: true }, { id: "retailer_slug", label: "Store", lazy_loaded: true }],
two = new Set(arrayTwo.map(({ id }) => id)),
result = arrayOne.filter(({ id }) => two.has(id));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to return the array of intersection between two array with Lodash?

I am trying to return the array of all the intersected array elements.
I got 2 arrays.
The array from api and the filter condition array.
Array from api is this
let somethingList = [
{
id: 'PROD108',
name: 'Headsweats Mid Cap',
CustomFields: [
{
name: 'Brand',
value: 'Headsweats',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD109',
name: 'Performance Liberty City Cycling Cap',
CustomFields: [
{
name: 'Brand',
value: 'Performance',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD110',
name: 'Castelli Logo Bandana',
CustomFields: [
{
name: 'Brand',
value: 'Castelli',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD159',
name: 'Performance Classic Sleeveless Jersey',
CustomFields: [
{
name: 'Eco',
value: 'False',
},
{
name: 'Color',
value: '#4CAF50',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD160',
name: 'Schwinn Evolution IC Sleeveless Jersey',
CustomFields: [
{
name: 'Brand',
value: 'Schwinn',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Color',
value: '#2196F3',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD161',
name: 'Performance Elite Short',
CustomFields: [
{
name: 'Brand',
value: 'Performance',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Color',
value: '#000000',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD162',
name: 'Andiamo! Padded Cycling Brief',
CustomFields: [
{
name: 'Eco',
value: 'False',
},
{
name: 'Color',
value: '#808080',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD163',
name: 'Fox Mojave Glove',
CustomFields: [
{
name: 'Brand',
value: 'Fox',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Color',
value: '#000000',
},
{
name: 'Test',
value: '0',
},
],
},
];
filter condition array.
let testingFilter = ['Fox', 'Performance'];
What I want to do is if the customfield value of array from api is intersected with testingFilter value
I want to push them into an array and return that new array.
But the code I written don't return an new array, What should I do to return a new array
let filteredProduct = [];
filteredProduct = _.filter(somethingList, (product) => {
if (testingFilter.length === 0) {
return somethingList;
} else {
// Here is the problem
return _.intersection(testingFilter, _.map(product.CustomFields, 'value'));
}
});
Expected Answer array
filteredProduct = [
{
id: 'PROD109',
name: 'Performance Liberty City Cycling Cap',
CustomFields: [
{
name: 'Brand',
value: 'Performance',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD161',
name: 'Performance Elite Short',
CustomFields: [
{
name: 'Brand',
value: 'Performance',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Color',
value: '#000000',
},
{
name: 'Test',
value: '0',
},
],
},
{
id: 'PROD163',
name: 'Fox Mojave Glove',
CustomFields: [
{
name: 'Brand',
value: 'Fox',
},
{
name: 'Eco',
value: 'False',
},
{
name: 'Color',
value: '#000000',
},
{
name: 'Test',
value: '0',
},
],
},
]
The following line taken from your code:
_.map(product.CustomFields, 'value')
Here, you get an array of all the values's of the CustomFields, if we check if there is an item from testinFilter present in that array, we can use that as the _filter return statement like so:
let filteredProduct = [];
filteredProduct = _.filter(somethingList, (product) => {
const allCustomFields = _.map(product.CustomFields, 'value');
return allCustomFields.some(r => testingFilter.indexOf(r) >= 0);
});
// We could rewrite the same code as a one-liner without the extra const like so:
let filteredProduct = _.filter(somethingList, (product) => _.map(product.CustomFields, 'value').some(r => testingFilter.indexOf(r) >= 0));
Snippet:
let testingFilter = ['Fox', 'Performance'];
let somethingList = [{id: 'PROD108', name: 'Headsweats Mid Cap', CustomFields: [{name: 'Brand', value: 'Headsweats', }, {name: 'Eco', value: 'False', }, {name: 'Test', value: '0', }, ], }, {id: 'PROD109', name: 'Performance Liberty City Cycling Cap', CustomFields: [{name: 'Brand', value: 'Performance', }, {name: 'Eco', value: 'False', }, {name: 'Test', value: '0', }, ], }, {id: 'PROD110', name: 'Castelli Logo Bandana', CustomFields: [{name: 'Brand', value: 'Castelli', }, {name: 'Eco', value: 'False', }, {name: 'Test', value: '0', }, ], }, {id: 'PROD159', name: 'Performance Classic Sleeveless Jersey', CustomFields: [{name: 'Eco', value: 'False', }, {name: 'Color', value: '#4CAF50', }, {name: 'Test', value: '0', }, ], }, {id: 'PROD160', name: 'Schwinn Evolution IC Sleeveless Jersey', CustomFields: [{name: 'Brand', value: 'Schwinn', }, {name: 'Eco', value: 'False', }, {name: 'Color', value: '#2196F3', }, {name: 'Test', value: '0', }, ], }, {id: 'PROD161', name: 'Performance Elite Short', CustomFields: [{name: 'Brand', value: 'Performance', }, {name: 'Eco', value: 'False', }, {name: 'Color', value: '#000000', }, {name: 'Test', value: '0', }, ], }, {id: 'PROD162', name: 'Andiamo! Padded Cycling Brief', CustomFields: [{name: 'Eco', value: 'False', }, {name: 'Color', value: '#808080', }, {name: 'Test', value: '0', }, ], }, {id: 'PROD163', name: 'Fox Mojave Glove', CustomFields: [{name: 'Brand', value: 'Fox', }, {name: 'Eco', value: 'False', }, {name: 'Color', value: '#000000', }, {name: 'Test', value: '0', }, ], }, ];
let filteredProduct = _.filter(somethingList, (product) => {
const allCustomFields = _.map(product.CustomFields, 'value');
return allCustomFields.some(r => testingFilter.indexOf(r) >= 0);
});
console.log(filteredProduct);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
Result:
[
{
"id": "PROD109",
"name": "Performance Liberty City Cycling Cap",
"CustomFields": [
{
"name": "Brand",
"value": "Performance"
},
{
"name": "Eco",
"value": "False"
},
{
"name": "Test",
"value": "0"
}
]
},
{
"id": "PROD161",
"name": "Performance Elite Short",
"CustomFields": [
{
"name": "Brand",
"value": "Performance"
},
{
"name": "Eco",
"value": "False"
},
{
"name": "Color",
"value": "#000000"
},
{
"name": "Test",
"value": "0"
}
]
},
{
"id": "PROD163",
"name": "Fox Mojave Glove",
"CustomFields": [
{
"name": "Brand",
"value": "Fox"
},
{
"name": "Eco",
"value": "False"
},
{
"name": "Color",
"value": "#000000"
},
{
"name": "Test",
"value": "0"
}
]
}
]
You can do:
let somethingList = [ { id: 'PROD108', name: 'Headsweats Mid Cap', CustomFields: [ { name: 'Brand', value: 'Headsweats', }, { name: 'Eco', value: 'False', }, { name: 'Test', value: '0', }, ], }, { id: 'PROD109', name: 'Performance Liberty City Cycling Cap', CustomFields: [ { name: 'Brand', value: 'Performance', }, { name: 'Eco', value: 'False', }, { name: 'Test', value: '0', }, ], }, { id: 'PROD110', name: 'Castelli Logo Bandana', CustomFields: [ { name: 'Brand', value: 'Castelli', }, { name: 'Eco', value: 'False', }, { name: 'Test', value: '0', }, ], }, { id: 'PROD159', name: 'Performance Classic Sleeveless Jersey', CustomFields: [ { name: 'Eco', value: 'False', }, { name: 'Color', value: '#4CAF50', }, { name: 'Test', value: '0', }, ], }, { id: 'PROD160', name: 'Schwinn Evolution IC Sleeveless Jersey', CustomFields: [ { name: 'Brand', value: 'Schwinn', }, { name: 'Eco', value: 'False', }, { name: 'Color', value: '#2196F3', }, { name: 'Test', value: '0', }, ], }, { id: 'PROD161', name: 'Performance Elite Short', CustomFields: [ { name: 'Brand', value: 'Performance', }, { name: 'Eco', value: 'False', }, { name: 'Color', value: '#000000', }, { name: 'Test', value: '0', }, ], }, { id: 'PROD162', name: 'Andiamo! Padded Cycling Brief', CustomFields: [ { name: 'Eco', value: 'False', }, { name: 'Color', value: '#808080', }, { name: 'Test', value: '0', }, ], }, { id: 'PROD163', name: 'Fox Mojave Glove', CustomFields: [ { name: 'Brand', value: 'Fox', }, { name: 'Eco', value: 'False', }, { name: 'Color', value: '#000000', }, { name: 'Test', value: '0', }, ], }, ];
let testingFilter = ['Fox', 'Performance'];
let filteredProducts = somethingList.filter(p =>
Array.from(p.CustomFields.values()) // iterable to array
.map(({value}) => value)
.some(value => testingFilter.includes(value)))
console.log(filteredProducts)

How to assign two fields data in header of react-csv

I am working on react-csv. I created an array for custom headers there I used header array and assign label and key. Currently, I have a situation of two fields to be assigned ( in the header, key is used to assign the reference of data fields). I tried but I failed could someone please help me how to achieve this goal.
Thanks
Code
headers = [
{
label: "id",
key: "user.id"
},
{
label: "Agent Name",
key: "user.firstName + user.lastName"
},
{
label: "Agent Email",
key: "user.email"
},
{
label: "Agent Phone",
key: "user.phoneNumber"
},
{
label: "Agent Commission",
key: "agentComission"
},
{
label: "Company Commission",
key: "companyComission"
},
{
label: "Total Sale",
key: "sale"
}
];
key: "user.firstName + user.lastName" },, as you see I want to assign this two fields but when I click on export it gives me empty cell.
I hope this will work
import { CSVLink } from "react-csv";
headers = [
{
label: "id",
key: "id"
},
{
label: "Agent Name",
key: "fullname"
},
{
label: "Agent Email",
key: "email"
},
{
label: "Agent Phone",
key: "phoneNumber"
},
{
label: "Agent Commission",
key: "agentComission"
},
{
label: "Company Commission",
key: "companyComission"
},
{
label: "Total Sale",
key: "sale"
}
];
data = [
{
id: 1,
fullname: "name of agent",
email: "test#gmail.com",
phoneNumber: 123456789,
agentComission: 'agent comission',
companyComission: 'company comission',
sale: 'sale',
},
{
id: 2,
fullname: "name of agent 2",
email: "test2#gmail.com",
phoneNumber: 123456789,
agentComission: 'agent comission 2',
companyComission: 'company comission 2',
sale: 'sale 2',
},
];
<CSVLink data={data} headers={headers}>
Download me
</CSVLink>;

change text of rows in type matrix surveyjs

I am building best employee survey project using surveyjs. When working in matrix type, I get trouble how to change text "employee1,employee2,employee3" with real name employee
see picture.
so far here is my code:
var json = {
title: "Software developer survey.",
pages: [
{
title: "Part 1",
questions: [
{
type: "matrix",
name: "Question1",
//isAllRowRequired: true,
title: "Please indicate if you agree or disagree with the following statements",
columns: [
{
value: 1,
text: "Strongly Disagree"
}, {
value: 2,
text: "Disagree"
}, {
value: 3,
text: "Neutral"
}, {
value: 4,
text: "Agree"
}, {
value: 5,
text: "Strongly Agree"
}
],
rows: [
{
value: "valueEmployee1",
text: "Employee1 ![Employee1](https://bezone.files.wordpress.com/2008/02/soeharto.jpg =50x50)"
}, {
value: "valueEmployee2",
text: "Employee2"
}, {
value: "valueEmployee3",
text: "Employee3"
}
]
},
//
]
},
thank you for your help
You can add matrix rows dynamically:
var json = {
questions: [
{
type: "matrix",
name: "score",
title: "Please score the employees in the list",
columns: [
{
value: 1,
text: "Bad"
}, {
value: 2,
text: "So-so"
}, {
value: 3,
text: "Good enough"
}, {
value: 4,
text: "Good"
}, {
value: 5,
text: "Excellent"
}
],
rows: [
]
}
]
};
window.survey = new Survey.Model(json);
var q = survey.getQuestionByName("score");
var employees = [{ id: "id1", name: "John"}, { id: "id2", name: "Ben"}, { id: "id3", name: "Chack"}]
employees.forEach(function(employee) {
q.rows.push(new Survey.ItemValue(employee.id, employee.name));
});
Here is the working sample - https://plnkr.co/edit/OMBt1n02Qc8f5znUmOHE?p=preview

Categories