Related
I have a table where I have a function that displays only the selected columns.
I store the selected columns (table headings) in an array selectedTableHeaders.
Now I want to make sure that I only display the selected columns in the table data.
So that means I want to create or filter a new array based on the properties stored in the selectedTableHeaders.
Furthermore, I want to make sure that the tableData is properly ordered, so if I for example disable table header 3 and then table header 6 and then enable 3 again, 3 is added later. That means that I also have to reorder the tableData based on the table headers.
How can I solve this?
const selectedTableHeaders = [
"table_header_1",
"table_header_3",
"table_header_5",
"table_header_6"
]
tableData [
{
"rowData": {
"table_header_1": "0",
"table_header_2": "data 2",
"table_header_3": "US",
"table_header_4": "data 4",
"table_header_5": "-",
"table_header_6": "data 6"
}
},
{
"rowData": {
"table_header_1": "0",
"table_header_2": "test 2",
"table_header_3": "GB",
"table_header_4": "test 4",
"table_header_5": "Y",
"table_header_6": "test data 6"
}
},
{
"rowData": {
"table_header_1": "0",
"table_header_2": "test 2",
"table_header_3": "DE",
"table_header_4": 70000118,
"table_header_5": "-",
"table_header_6": "test table 6"
}
}
]
I have tried something like:
this.tableData.forEach((tableItem) => {
const newArray = Object.assign(...selectedTableHeaders.map(k => ({ [k]: tableItem[k] })));
})
But then I don't get the values in the newArray.
Is there a better way to handle this and get also the values of the properties in the new array?
So I want to create a new array with only the selected columns.
And how can I make sure that the table data is well-ordered, based on the table headings.
So eg:
If this is the order for the headings:
"table_header_2",
"table_header_1",
"table_header_5",
"table_header_4"
That the rowData also becomes like this:
"rowData": {
"table_header_2": "data 2 ",
"table_header_1": "0",
"table_header_5": "-",
"table_header_4": "data 4",
}
You could just map your fields, seen as there already in the order you want, and then get the values using the keys,
reg.
const selectedTableHeaders = [
"table_header_1",
"table_header_3",
"table_header_5",
"table_header_6",
];
const tableData = [
{
rowData: {
table_header_1: "0",
table_header_2: "data 2 ",
table_header_3: "US",
table_header_4: "data 4",
table_header_5: "-",
table_header_6: "data 6",
},
},
{
rowData: {
table_header_1: "0",
table_header_2: "test 2",
table_header_3: "GB",
table_header_4: "test 4",
table_header_5: "Y",
table_header_6: "test data 6",
},
},
{
rowData: {
table_header_1: "0",
table_header_2: "test 2",
table_header_3: "DE",
table_header_4: 70000118,
table_header_5: "-",
table_header_6: "test table 6",
},
},
];
function filter(src, fields) {
return src.map((row) => ({
rowData: Object.fromEntries(
fields.map((m) => [m, row.rowData[m]])),
}));
}
console.log(filter(tableData, selectedTableHeaders));
You can simply achieve it by iterating the array object.
Working Demo :
const selectedTableHeaders = [
"table_header_1",
"table_header_3",
"table_header_5",
"table_header_6"
]
const tableData = [
{
"rowData": {
"table_header_1": "0",
"table_header_2": "data 2 ",
"table_header_3": "US",
"table_header_4": "data 4",
"table_header_5": "-",
"table_header_6": "data 6"
}
}, {
"rowData": {
"table_header_1": "0",
"table_header_2": "test 2",
"table_header_3": "GB",
"table_header_4": "test 4",
"table_header_5": "Y",
"table_header_6": "test data 6"
}
}, {
"rowData": {
"table_header_1": "0",
"table_header_2": "test 2",
"table_header_3": "DE",
"table_header_4": 70000118,
"table_header_5": "-",
"table_header_6": "test table 6"
}
}
];
const res = tableData.map((rowDataObj) => {
Object.keys(rowDataObj.rowData).forEach((headerKey) => {
if (!selectedTableHeaders.includes(headerKey)) {
delete rowDataObj.rowData[headerKey]
}
});
return rowDataObj.rowData;
});
console.log(res);
I have a json array where it contains an objects having name and rating fields.I want to filter that array where rating is 5.It might be the easy one find but I got stuck.
Below is my json object.
let products = [
{
"name" : "product 1",
"rating" : 5
},
{
"name" : "product 2",
"rating" : 4
},
{
"name" : "product 3",
"rating" : 5
},
{
"name" : "product 4",
"rating" : 2
}]
Here I am using filter functionality but unable to get How can I use it properly.
This is the function I have written but its not working.
const prod = (products) => {
products.filter((proct) => {
if(proct === 5){
console.log(proct.name);
}
});
}
prod(products);
Someone let me know what I am doing wrong.
filter function must return a boolean as result
Function is a predicate, to test each element of the array. Return a value that coerces to true to keep the element, or to false otherwise.
Array.prototype.filter
let products = [{ "name": "product 1", "rating": 5 }, { "name": "product 2", "rating": 4 }, { "name": "product 3", "rating": 5 }, { "name": "product 4", "rating": 2 } ]
products = products.filter(({rating}) => rating === 5)
console.log(products)
Each item in your array is an object, and I guess you are looking for rating===5.
Your function should be:
let products = [{ "name": "product 1", "rating": 5 }, { "name": "product 2", "rating": 4 }, { "name": "product 3", "rating": 5 }, { "name": "product 4", "rating": 2 } ]
const prod = (products) => {
products.filter((proct) => {
if (proct.rating === 5) {
console.log(proct.name);
return true;
}
return false
});
}
prod(products)
Getting just name key:
Take a look at map function which create a new array from old array:
.map(({name}) => name)
Full code:
let products = [{ "name": "product 1", "rating": 5 }, { "name": "product 2", "rating": 4 }, { "name": "product 3", "rating": 5 }, { "name": "product 4", "rating": 2 } ]
products = products.filter(({rating}) => rating === 5).map(({name}) => name)
console.log(products)
Your code is not checking the property. But the object itself. Use the . operator to check the specific property:
let products = [
{
"name" : "product 1",
"rating" : 5
},
{
"name" : "product 2",
"rating" : 4
},
{
"name" : "product 3",
"rating" : 5
},
{
"name" : "product 4",
"rating" : 2
}]
const prod = (products) => {
products.filter((proct) => {
if(proct.rating === 5){
console.log(proct.name);
}
});
}
prod(products);
Your condition is comparing proct, an object, to the value 5. You probably forgot to access the rating property of proct:
products.filter((proct) => {
if(proct.rating === 5){
console.log(proct.name);
}
});
However, you are using filter wrong. Filter is a method whose entire point is to get all the elements in the array that answer a condition and return them, and not just iterate over an array and execute code (that's what forEach is for). A more correct code would be:
const filteredProducts = products.filter((proct) => proct.rating === 5);
console.log(filteredProducts); // [{ name: "product 1", rating: 5 }, { name: "product 3", rating: 5 }]
filteredProducts.forEach((proct) => console.log(proct.name));
This solution first retrieves all the products whose rating is 5 and then iterates over each of them to print their name.
Hopefully someone can help me out here.
I am building an angular app with SQLite database which stores existing values. I need to compare these values from a json array received over http.
They should be matched by code, I want to compare the existing values with the update values add the property "active" = 1 otherwise active = 0 .
I tried a double foreach loop below, but I guess what's happening is the index is off so the results are not accurate in my actual application.
I have lodash available if there is some way to do this using that.
Any help would be much appreciated.
How can I get the following output
/*epected output
[{
"name": "Person 1"
"code": '001',
"active": '1'
},
{
"name": "Person 2"
"code": '002',
"active": '1'
},
{
"name": "Person 3"
"code": '003',
"active": '0' // note active 0 since doesnt exist in exsting
}
]*/
and what I tried along with 500 other things.
const existing = [{
"name": "Person 1",
"code": '001',
},
{
"name": "Person 2",
"code": '002',
},
];
const update = [{
"name": "Person 1",
"code": '001',
},
{
"name": "Person 2",
"code": '002',
},
{
"name": "Person 3",
"code": '003',
},
];
existing.forEach(element => {
update.forEach(test => {
if (element.code === test.code) {
element.avtive = true;
} else {
element.avtive = false;
}
});
return element;
});
console.log(existing);
/*epected output
[{
"name": "Person 1"
"code": '001',
"active": '1'
},
{
"name": "Person 2"
"code": '002',
"active": '1'
},
{
"name": "Person 3"
"code": '003',
"active": '0' // note active 0 since doesnt exist in exsting
}
]*/
Here is what should work for you. All existing code are extracted and then, for each updated value it is checked whether code exists in existingCodes array.
const existingCodes = existing.map((e) => e.code);
const result = updated.map((e) => ({
...e,
active: existingCodes.includes(e.code) ? '1' : '0'
});
If includes doesn't work for you on IE, you can replace this line existingCodes.includes(e.code) with existingCodes.filter((code) => code === e.code).length.
I like #radovix answer above, which worked for me, I came up with something slightly more long-winded, but which gives the same end result, but also separate lists of active and inactive:
let active = update.filter(item =>{
return existing.find(exist=> exist.code == item.code);
});
let inactive = update.filter(item =>{
return !existing.find(exist=> exist.code == item.code);
});
active = active.map(item=>({...item, active: '1'}));
inactive= inactive.map(item=>({...item, active: '0'}));
const merged = [...this.active, ...this.inactive];
You can see both ways working here: https://stackblitz.com/edit/angular-merge-arrays-update-property
You can use reduce, find and remove item from update array as
let result= existing.reduce((acc, item)=>{
let found = update.find(c => c.name == item.name);
if (found != undefined) {
const index = update.indexOf(found);
if (index > -1) {
update.splice(index, 1);
}
}
item.active = true;
acc.push(item);
return acc;
},[]);
update.map(c=> c.active = false);
//console.log(update)
result = result.concat(update);
console.log(result);
const existing = [{
"name": "Person 1",
"code": '001',
},
{
"name": "Person 2",
"code": '002',
},
];
const update = [{
"name": "Person 1",
"code": '001',
},
{
"name": "Person 2",
"code": '002',
},
{
"name": "Person 3",
"code": '003',
},
];
let result= existing.reduce((acc, item)=>{
let found = update.find(c => c.name == item.name);
if (found != undefined) {
const index = update.indexOf(found);
if (index > -1) {
update.splice(index, 1);
}
}
item.active = true;
acc.push(item);
return acc;
},[]);
update.map(c=> c.active = false);
//console.log(update)
result = result.concat(update);
console.log(result);
I would like to find number of items which has specific text using js filter method.
var num =
[
{
"name": "name1 ",
"category": "test"
},
{
"name": " name2",
"category": "test2"
},
{
"name": "name3",
"category": "cat3"
},
{
"name": "name 4",
"category": "cat 4"
}
];
num is an object;
Now, i want to find number of categories which has text 'cat'. So i want the result 2. How to get that using filter method.
here's how you can do it
var num =
[
{
"name": "name1 ",
"category": "test"
},
{
"name": " name2",
"category": "test2"
},
{
"name": "name3",
"category": "cat3"
},
{
"name": "name 4",
"category": "cat 4"
}
];
console.log( num.filter(i => i.category.indexOf("cat") === 0).length )
num is an object;
True, but specifically it's an array object.
You could use filter for this, but reduce would be the more appropriate option if you don't want the array of matching results:
var result = num.reduce(function(sum, entry) => sum + (entry.category.includes("cat") ? 1 : 0), 0);
Live Example:
var num =
[
{
"name": "name1 ",
"category": "test"
},
{
"name": " name2",
"category": "test2"
},
{
"name": "name3",
"category": "cat3"
},
{
"name": "name 4",
"category": "cat 4"
}
];
var result = num.reduce(function(sum, entry) {
return sum + (entry.category.includes("cat") ? 1 : 0);
}, 0);
console.log(result);
Or with ES2015+:
const num =
[
{
"name": "name1 ",
"category": "test"
},
{
"name": " name2",
"category": "test2"
},
{
"name": "name3",
"category": "cat3"
},
{
"name": "name 4",
"category": "cat 4"
}
];
const result = num.reduce((sum, entry) => sum + (entry.category.includes("cat") ? 1 : 0), 0);
console.log(result);
Or of course, a simple for loop.
This is fairly simple. In ES6 the solution would be this:
const countOfCats = num.filter(entry => entry.category.match('cat')).length;
Another way could be:
const countOfCats = num.filter(entry => entry.contains("cat")).length;
I need to filter JSON result using jQuery grep.My JSON result look like this:
var data = { "items":[
{
"Name": "Name 1",
"City": "city1"
},
{
"Name": "Name 2",
"City": "city2"
},
{
"Name": "Name 3",
"City": "cat1"
}
]}
Filter this JSON with array of Name example:
var Name= ["Name 1","Name 2"];
Use jQuery.grep() to filter the items array
var data = {
"items": [{
"Name": "Name 1",
"City": "city1"
}, {
"Name": "Name 2",
"City": "city2"
}, {
"Name": "Name 3",
"City": "cat1"
}]
}
var name = ["Name 1", "Name 2"];
var res = $.grep(data.items, function(v) {
return name.indexOf(v.Name) > -1;
});
document.write('<pre>' + JSON.stringify(res, 0, 3) + '</pre>');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Or with filter()
var data = {
"items": [{
"Name": "Name 1",
"City": "city1"
}, {
"Name": "Name 2",
"City": "city2"
}, {
"Name": "Name 3",
"City": "cat1"
}]
}
var name = ["Name 1", "Name 2"];
var res = data.items.filter(function(v) {
return name.indexOf(v.Name) > -1;
});
document.write('<pre>' + JSON.stringify(res, 0, 3) + '</pre>');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
If you need to get the string array from existing object array using $.grep so first use $.grep for filter the object and then use $.map for get the specific output from the result object like below code will help you.
Filter the object using $.grep
var data = {
"items": [
{
"Name": "Name 1",
"City": "city1"
},
{
"Name": "Name 2",
"City": "city2"
},
{
"Name": "Name 3",
"City": "cat1"
}
]
};
var objret = $.grep(data.items, function (n, i) {
return n.Name == 'Name 1' || n.Name == 'Name 2';
});
Now you have result object in the objret variable now convert the object result to your string array out put using $.map like :-
Get OutPut
var array = $.map(objret, function (value, index) {
return [value.Name];
});
so in the array have your required output.
I think is the same questione exposed here:
[question] Filtering a json array using jquery grep
However json array are like string, or you get an array from that or u can access it only like string.
Use jquery grep to recreate the array then access it via index to compare value