Exclude items from Array.map() - javascript

I am trying to exclude items that contain Packages in packageData.type. To show only the packageData that has items with packageData.type as Add-on.
Array is as example
{
"packageData": [
{
"title": "Title 1",
"type": [
"Packages"
]
},
{
"title": "Title 2",
"type": [
"Add-on"
]
},
{
"title": "Title 3",
"type": [
"Add-on"
]
},
{
"title": "Title 4",
"type": [
"Add-on"
]
}
]
}
and this is how I am currently trying to remove results which is giving zero results.
<ul>
{packageData.map(function() {
if (packageData.type ==! "Packages") {
return (
<li key={packageData.id}>
<a>
<img src={packageData.heroImage.sizes.src} alt=""/>
<h3>{packageData.title}</h3>
</a>
</li> );
} else {
return null;
};
})}
</ul>
How can I make this work? Or should I be filtering these results prior to displaying and then map the returned items?

You have to use filter before map, Filter will filter the array and then map will iterate through array. Below is the sample code
var data = {
"packageData": [
{
"title": "Title 1",
"type": [
"Packages"
]
},
{
"title": "Title 2",
"type": [
"Add-on"
]
},
{
"title": "Title 3",
"type": [
"Add-on"
]
},
{
"title": "Title 4",
"type": [
"Add-on"
]
}
]
};
data.packageData.filter((item) => { return item.type[0] !== 'Packages' }).map((item)=> { console.log(item); });

Related

mapping arrays together with unique keys

I am trying to map two arrays together and then create unique keys for the values in that new array. I am working with multiple different arrays.
My arrays look like this
var arr =
[
{
"title": "title 1"
"projects": [
"project1",
"project2",
"project3",
"project4",
"project5",
"project6"
],
"project_links": [
"link1",
"link2",
"link3",
"link4",
"link5",
"link6"
]
},
{
"title": "title 2"
"projects": [
"project1",
"project2",
"project3"
],
"project_links": [
"link1",
"link2",
"link3"
]
},
{
"title": "title 3"
"projects": [
"project1",
"project2",
"project3",
"project4",
"project5"
],
"project_links": [
"link1",
"link2",
"link3",
"link4",
"link5"
]
},
{
"title": "title 4"
"projects": [
"project1",
"project2",
"project3",
"project4",
"project5"
],
"project_links": [
"link1",
"link2",
"link3",
"link4",
"link5"
]
},
{
"title": "title 5"
"projects": [
"project1"
],
"project_links": [
"link1"
]
}
]
This is what I have tried
for (let i = 0; i < arr.length; i++) {
var test = arr[i].projects.map((x, y) => [x, arr[i].project_links[y]])
for (let n = 0; n < test.length; n++) {
arr[i].custom = {};
arr[i].custom["projects"] = [];
arr[i].custom["projects"].push({
name: test[n][0],
link: test[n][1]
});
}
}
I want my end result to look like this
var arr =
[
{
"title": "title 1"
"custom": {
"projects": [
{
"project_name": "project1",
"link": "link1"
},
{
"project_name": "project2",
"link": "link2"
},
{
"project_name": "project3",
"link": "link3"
},
{
"project_name": "project4",
"link": "link5"
},
{
"project_name": "project5",
"link": "link5"
},
{
"project_name": "project6",
"link": "link6"
}
]
}
},
{
"title": "title 2"
"custom": {
"projects": [
{
"project_name": "project1",
"link": "link1"
},
{
"project_name": "project2",
"link": "link2"
},
{
"project_name": "project3",
"link": "link3"
}
]
}
},
{
"title": "title 3"
"custom": {
"projects": [
{
"project_name": "project1",
"link": "link1"
},
{
"project_name": "project2",
"link": "link2"
},
{
"project_name": "project3",
"link": "link3"
},
{
"project_name": "project4",
"link": "link4"
},
{
"project_name": "project5",
"link": "link5"
}
]
}
},
...etc
]
I'm able to map the arrays together and create unique key names for the values, however I don't know how I can have those arrays in the correct objects. I want to be able to push it into the original arr instead of creating a brand new array. I can delete the unwanted parts of the array later. Thanks in advance.
Using Array#map, iterate over the array.
In every iteration, to get custom.projects, again using Array#map, iterate over the current projects array and using the second parameter (index) get the corresponding links:
const arr = [
{
title: "title 1",
projects: [ "project1", "project2", "project3", "project4", "project5", "project6" ],
project_links: ["link1", "link2", "link3", "link4", "link5", "link6"]
},
{
title: "title 2",
projects: ["project1", "project2", "project3"],
project_links: ["link1", "link2", "link3"]
},
{
title: "title 3",
projects: ["project1", "project2", "project3", "project4", "project5"],
project_links: ["link1", "link2", "link3", "link4", "link5"]
},
{
title: "title 4",
projects: ["project1", "project2", "project3", "project4", "project5"],
project_links: ["link1", "link2", "link3", "link4", "link5"]
},
{
title: "title 5",
projects: ["project1"],
project_links: ["link1"]
}
];
const res = arr.map(({ title, projects = [], project_links = [] }) => ({
title,
custom: {
projects: projects.map((project_name, i) => ({ project_name, link: project_links[i] }))
}
}));
console.log(res);

Filter inside a nested array with objects

I have an array that contains three book objects. Each book object has an array of bookIds . I want to filter by bookId (3,1) in a fast and efficient way since my array will grow up easly in the future. I tried with map, but it change my original array even with a deepCopy ! Is there a way to use the filter function instead without using recursivity ?
this.booksList =
[
{
"books": [
{
"bookId": 3
},
{
"bookId": 2
}
],
"id": 1,
"name": "Name 1",
"description": "desc 1"
},
{
"books": [
{
"bookId": 5
},
{
"bookId": 2
}
],
"id": 2,
"name": "Name 2",
"description": "desc 2"
},
{
"books": [
{
"bookId": 1
},
{
"bookId": 3
}
],
"id": 3,
"name": "Name 3",
"description": "desc 3"
}
]
The map approach :
let results = this.books.map(function (book) {
book.books = book.books.filter(x => x.bookId == 1 || x.bookId == 3);
return book;
}).filter(({ books }) => books.length);
Result with map : not expected result !
[
{
"books": [
{
"bookId": 3
}
],
"id": 1,
"name": "Name 1",
"description": "desc 1"
},
{
"books": [
{
"bookId": 1
},
{
"bookId": 3
}
],
"id": 3,
"name": "Name 3",
"description": "desc 3"
}
]
expected results :
[
{
"books": [
{
"bookId": 3
},
{
"bookId": 2
}
],
"id": 1,
"name": "Name 1",
"description": "desc 1"
},
{
"books": [
{
"bookId": 1
},
{
"bookId": 3
}
],
"id": 3,
"name": "Name 3",
"description": "desc 3"
}
]
Thanks,
I think you are looking for filter and some -
const input =
[{books:[{bookId:3},{bookId:2}],id:1,name:"Name 1",description:"desc 1"},{books:[{bookId:5},{bookId:2}],id:2,name:"Name 2",description:"desc 2"},{books:[{bookId:1},{bookId:3}],id:3,name:"Name 3",description:"desc 3"}]
const query =
[3, 1]
const result =
input.filter(({ books = [] }) =>
books.some(({ bookId = null }) => query.includes(bookId))
)
console.log(JSON.stringify(result, null, 2))
Output -
[
{
"books": [
{
"bookId": 3
},
{
"bookId": 2
}
],
"id": 1,
"name": "Name 1",
"description": "desc 1"
},
{
"books": [
{
"bookId": 1
},
{
"bookId": 3
}
],
"id": 3,
"name": "Name 3",
"description": "desc 3"
}
]
const booksList=[
{books:[{bookId:3},{bookId:2}],id:1,name:"Name 1",description:"desc 1"},
{books:[{bookId:5},{bookId:2}],id:2,name:"Name 2",description:"desc 2"},
{books:[{bookId:1},{bookId:3}],id:3,name:"Name 3",description:"desc 3"},
];
const byBookIDs = (...IDs) =>
booksList.filter(b => b.books.some(b => IDs.includes(b.bookId)));
console.log(byBookIDs(1, 3));
MDN Array Filter - to return a subset
MDN Array Some - to match (and return) as soon as some
MDN Array Includes - to find item in array

Restructuring JSON in JavaScript

I have this JSON which I'm parsing using NodeJS and it needs to be restructured into the second JSON which I've added below.
In the first JSON, the rows object has two pages objects (any number of pages objects can be present) which contains all the same keys and values with the exception of values and display keys.
{
"pages": [
{
"label": "SomeLabel",
"name": "Some",
"sections": [
{
"type": "Repeat",
"label": "Label 1",
"name": "Name 1",
"rows": [
{
"pages": [
{
"label": "Label 1",
"name": "Name 1",
"sections": [
{
"type": "Flow",
"label": "Label 2",
"name": "Name 2",
"answers": [
{
"label": "Question Label",
"question": "Question",
"values": [
"Value A"
],
"valuesMetadata": [
{
"display": "Display A",
"row": {
"columns": []
}
}
]
}
]
}
]
}
]
},
{
"pages": [
{
"label": "Label 1",
"name": "Name 1",
"sections": [
{
"type": "Flow",
"label": "Label 2",
"name": "Name 2",
"answers": [
{
"label": "Question Label",
"question": "Question",
"values": [
"Value B"
],
"valuesMetadata": [
{
"display": "Display B",
"row": {
"columns": []
}
}
]
}
]
}
]
}
]
}
],
"footer": null
}
]
}
]
}
In the second JSON the rows object has a single pages object, inside of which the values and display keys have multiple values (the non-common values).
{
"pages": [
{
"label": "SomeLabel",
"name": "Some",
"sections": [
{
"type": "Repeat",
"label": "Label 1",
"name": "Name 1",
"rows": [
{
"pages": [
{
"label": "Label 1",
"name": "Name 1",
"sections": [
{
"type": "Flow",
"label": "Label 2",
"name": "Name 2",
"answers": [
{
"label": "Question Label",
"question": "Question",
"values": [
"Value A",
"Value B"
],
"valuesMetadata": [
{
"display": [
"Display A",
"Display B"
],
"row": {
"columns": []
}
}
]
}
]
}
]
}
]
}
],
"footer": null
}
]
}
]
}
So, I want to know the fast and easy steps to do this. Please let me know the process and methods to solve this.
Thanks
If I understand you correctly, you want to combine all pages in a single page that holds all information.
This can be achieved using the Array.reduce function. reduce takes an array and combines all elements to a single value using a function (provided by you) to combine the first two elements until only one is left (i.e. 1 * 2 => new1; new1 * 3 => new2 where * represents your function).
Your problem would look something like this:
rows[0].pages = rows[0].pages.reduce((currentElement, currentState) => {
if (!currentState) { // first iteration return first element but make sure display is an array
currentElement.sections[0].answers[0].valuesMetadata[0].display =
[currentElement.sections[0].answers[0].valuesMetadata[0].display];
return currentElement;
}
// add values of current element to arrays in current state
currentState.sections[0].answers[0].values
.concat(currentElement.sections[0].answers[0].values);
currentState.sections[0].answers[0].valuesMetadata[0].display
.concat(currentElement.sections[0].answers[0].valuesMetadata[0].display);
return currentState;
});
currentElement is the object of the array that is currently reduced, currentState is the intermediate result of the reduction.
PS:
The object looks like you are way too many arrays where you would not need them. The given code snippet works only for the first element in each array (hence the [0]s. If you really do have multiple values in each array you would have to iterate over all of those accordingly.

iterate through Json array without having a key

First of all, this question might have been asked several times already, but every thread I found didn't help me. I would appreciate if one could rewrite my function below.
I have the following array with Json objects.
The goal is to get the "url" values. Right now I get every value from that array.
a = [{
"result": [{
"name": [
"name"
],
"url": [
"www.bar.com"
]
},
{
"name": [
"name 2"
],
"url": [
"www.bar.org"
]
},
{
"name": [
"name 1"
],
"url": [
"www.bar.biz"
]
},
{
"name": [
"name 3"
],
"url": [
"www.bar.jp"
]
}
]
}];
document.getElementById("foo").innerHTML = "How to explicitly get the url value?'";
loopThrough(a);
function loopThrough(obj) {
for (var key in obj) {
// skip loop if the property is from prototype
if (!obj.hasOwnProperty(key)) continue;
if (typeof obj[key] !== 'object') {
console.log(obj[key]);
} else {
loopThrough(obj[key]);
}
}
}
<div id="foo">
</div>
How would I access each "url" element in this array?
Maybe there is also a smarter solution than this.
Thank you in advance.
a = [{
"result": [{
"name": [
"name"
],
"url": [
"www.bar.com"
]
},
{
"name": [
"name 2"
],
"url": [
"www.bar.org"
]
},
{
"name": [
"name 1"
],
"url": [
"www.bar.biz"
]
},
{
"name": [
"name 3"
],
"url": [
"www.bar.jp"
]
}
]
}];
loopThrough(a);
// Uses ES6 syntax
function loopThrough(obj) {
obj[0].result.forEach(r => console.log(r.url[0]));
}
try it yourself.
var a = [{
"result": [{
"name": [
"name"
],
"url": [
"www.bar.com"
]
},
{
"name": [
"name 2"
],
"url": [
"www.bar.org"
]
},
{
"name": [
"name 1"
],
"url": [
"www.bar.biz"
]
},
{
"name": [
"name 3"
],
"url": [
"www.bar.jp"
]
}
]
}];
var urls=a[0].result.reduce(function(urls,it){
return urls.concat(it.url);
},[]);
console.log(urls);

xpath or Defiant.js and getting node information

I have my json:
{
"data": {
"header": {
"version": 1,
"last_updated": "2015-09-16T14:09:22Z"
},
"frequent" : {
"keywords": [
{
"keyword":"roi",
"keyword":"subjectrecord",
"keyword":"evidence",
"keyword":"case",
"keyword":"account",
"keyword":"supervisor",
"keyword":"legacy tecs"
}
]
},
"body": {
"items": [
{
"item": {
"type": "pdf",
"title": "title 1",
"updated_time": "2015-09-16T14:09:22Z",
"keywords": [
{
"keyword":"supervisor"
},
{
"keyword":"manager"
},
{
"keyword":"title 1"
}
]
}
},
{
"item": {
"type": "pdf",
"title": "title 2",
"updated_time": "2015-09-16T14:09:22Z",
"keywords": [
{
"keyword":"supervisor"
}
]
}
},
{
"item": {
"type": "pdf",
"title": "title 3",
"updated_time": "2015-09-16T14:09:22Z"
}
}
]
}
}
}
What i want to be able to do is search "body" and return any items where a match occurs with the keyword. So for instance, if I search "supervisor" my results should look like:
"item": {
"type": "pdf",
"title": "title 1",
"updated_time": "2015-09-16T14:09:22Z",
"keywords": [
{
"keyword":"supervisor"
},
{
"keyword":"manager"
},
{
"keyword":"title 1"
}
]
}
},
{
"item": {
"type": "pdf",
"title": "title 2",
"updated_time": "2015-09-16T14:09:22Z",
"keywords": [
{
"keyword":"supervisor"
}
]
}
}
Doing the following only returns the keyword.
var results = JSON.search(potentials, '//*[keyword="'+query+'"]');
put /.. at the end of the query
var results = JSON.search(potentials, '//*[keyword="'+query+'"]/..');

Categories

Resources