Flatten arrays within object of arrays with data from parent object - javascript

I want to flatten some arrays nested in each object of an array of objects to return an array of objects with data from the parent objects. Quite a mouthful but perhaps some example json will help explain.
My current data and code is:
const galleries = [
{
"gallery": [
{
"url": "https://cdn.example.com/images/0e7f6dfeaade4b63ac4e18d25da3b32099c6a19f-1080x1080.jpg"
},
{
"url": "https://cdn.example.com/images/47688945188ac5788e29054b2be1fda95d474ea9-1080x1080.jpg"
},
{
"url": "https://cdn.example.com/images/a31b2ceec33211139918a21a75faaea914f47e39-1080x1080.jpg"
}
],
"slug": "stella-mccartney",
"title": "Stella McCartney"
},
{
"gallery": [
{
"url": "https://cdn.example.com/images/da8818751ed5f871ac3c48adc7211e30fa7e4e33-4555x5906.jpg"
},
{
"url": "https://cdn.example.com/images/0618ca397c55949629d04127519955796b6f7009-4426x5739.jpg"
}
],
"slug": "esquire",
"title": "Esquire"
},
{
"gallery": [
{
"url": "https://cdn.example.com/images/60e617f13cfe8314aa2fb1b90973792252011915-3000x1827.jpg"
},
{
"url": "https://cdn.example.com/images/c9c7443cad60078892fe536b8be27080e780e847-2400x3000.jpg"
}
],
"slug": "matches",
"title": "Matches"
},
{
"gallery": [
{
"url": "https://cdn.example.com/images/3b4be2e581ec8eb542bb4e77e2e7de8858ca3229-5339x3000.jpg"
}
],
"slug": "testing-project-2",
"title": "Testing Project 2"
}
]
const AllThumbnails = [].concat(
...galleries.map((gallery) => ({
image: gallery.gallery,
slug: gallery.slug,
}))
)
console.log(AllThumbnails)
My ideal output is:
[
{
"url": "https://cdn.example.com/images/0e7f6dfeaade4b63ac4e18d25da3b32099c6a19f-1080x1080.jpg",
"slug": "stella-mccartney"
},
{
"url": "https://cdn.example.com/images/47688945188ac5788e29054b2be1fda95d474ea9-1080x1080.jpg",
"slug": "stella-mccartney"
},
{
"url": "https://cdn.example.com/images/a31b2ceec33211139918a21a75faaea914f47e39-1080x1080.jpg",
"slug": "stella-mccartney"
},
{
"url": "https://cdn.example.com/images/da8818751ed5f871ac3c48adc7211e30fa7e4e33-4555x5906.jpg",
"slug": "esquire"
},
{
"url": "https://cdn.example.com/images/0618ca397c55949629d04127519955796b6f7009-4426x5739.jpg",
"slug": "esquire"
},
{
"url": "https://cdn.example.com/images/60e617f13cfe8314aa2fb1b90973792252011915-3000x1827.jpg",
"slug": "matches"
},
{
"url": "https://cdn.example.com/images/c9c7443cad60078892fe536b8be27080e780e847-2400x3000.jpg",
"slug": "matches"
},
{
"url": "https://cdn.example.com/images/3b4be2e581ec8eb542bb4e77e2e7de8858ca3229-5339x3000.jpg",
"slug": "testing-project-2",
}
]
How can I append the slug property correctly? Any help/pointers would be much appreciated.

You could use
const allThumbnails = galleries.map(parent =>
parent.gallery.map(g => ({url: g.url, slug: parent.slug}))).flat();
.map() will map each parent object to an array of {url, slug}, and then .flat() will flatten these nested arrays.
const galleries = [
{
"gallery": [
{
"url": "https://cdn.example.com/images/0e7f6dfeaade4b63ac4e18d25da3b32099c6a19f-1080x1080.jpg"
},
{
"url": "https://cdn.example.com/images/47688945188ac5788e29054b2be1fda95d474ea9-1080x1080.jpg"
},
{
"url": "https://cdn.example.com/images/a31b2ceec33211139918a21a75faaea914f47e39-1080x1080.jpg"
}
],
"slug": "stella-mccartney",
"title": "Stella McCartney"
},
{
"gallery": [
{
"url": "https://cdn.example.com/images/da8818751ed5f871ac3c48adc7211e30fa7e4e33-4555x5906.jpg"
},
{
"url": "https://cdn.example.com/images/0618ca397c55949629d04127519955796b6f7009-4426x5739.jpg"
}
],
"slug": "esquire",
"title": "Esquire"
},
{
"gallery": [
{
"url": "https://cdn.example.com/images/60e617f13cfe8314aa2fb1b90973792252011915-3000x1827.jpg"
},
{
"url": "https://cdn.example.com/images/c9c7443cad60078892fe536b8be27080e780e847-2400x3000.jpg"
}
],
"slug": "matches",
"title": "Matches"
},
{
"gallery": [
{
"url": "https://cdn.example.com/images/3b4be2e581ec8eb542bb4e77e2e7de8858ca3229-5339x3000.jpg"
}
],
"slug": "testing-project-2",
"title": "Testing Project 2"
}
];
const allThumbnails = galleries.map(parent => parent.gallery.map(g => ({url: g.url, slug: parent.slug}))).flat();
console.log(allThumbnails);

you can use reduce to do this
const galleries = [{
"gallery": [{
"url": "https://cdn.example.com/images/0e7f6dfeaade4b63ac4e18d25da3b32099c6a19f-1080x1080.jpg"
},
{
"url": "https://cdn.example.com/images/47688945188ac5788e29054b2be1fda95d474ea9-1080x1080.jpg"
},
{
"url": "https://cdn.example.com/images/a31b2ceec33211139918a21a75faaea914f47e39-1080x1080.jpg"
}
],
"slug": "stella-mccartney",
"title": "Stella McCartney"
},
{
"gallery": [{
"url": "https://cdn.example.com/images/da8818751ed5f871ac3c48adc7211e30fa7e4e33-4555x5906.jpg"
},
{
"url": "https://cdn.example.com/images/0618ca397c55949629d04127519955796b6f7009-4426x5739.jpg"
}
],
"slug": "esquire",
"title": "Esquire"
},
{
"gallery": [{
"url": "https://cdn.example.com/images/60e617f13cfe8314aa2fb1b90973792252011915-3000x1827.jpg"
},
{
"url": "https://cdn.example.com/images/c9c7443cad60078892fe536b8be27080e780e847-2400x3000.jpg"
}
],
"slug": "matches",
"title": "Matches"
},
{
"gallery": [{
"url": "https://cdn.example.com/images/3b4be2e581ec8eb542bb4e77e2e7de8858ca3229-5339x3000.jpg"
}],
"slug": "testing-project-2",
"title": "Testing Project 2"
}
]
const flatten = galleries.reduce((acc, curr) => {
curr.gallery.forEach(g => {
acc.push({
url: g.url,
slug: curr.slug
});
});
return acc;
}, []);
console.log(flatten);

Looks like I'm a little late with my answer, I think Kirill's solution is going to be the most practical one.
Here is my solution anyways:
let newArray = []
galleries.forEach(function (gallery) {
gallery["gallery"].forEach(function (url) {
newArray.push({"url": url["url"], "slug": gallery["slug"]})
})
})

Some of these answers are very close to mine, but here's mine using forEach with ES6 syntax, which in my opinion is more readable:
const allThumbnails = new Array();
thumbnails.forEach(set => {
set.galleries.forEach(item => {
allThumbnails.push({url: item.url, slug: set.slug};
});
});

Related

Remove duplicated objects according to one of their key

I have an array which has only objects in it and I would like to remove duplicated objects based one of their key value which is val.js.url but wanna make it remaining object the latest one among the duplicated objects so I basically used reverse() in my code`.
My array:
[
{
"id": "js_1oc3uiteki22",
"tab": {
"title": "title 1",
"url": "http://google.com"
},
"js": {
"initiator": "https://google.com",
"url": "http://url.com"
}
},
{
"id": "js_1oc3uiteki22",
"tab": {
"title": "title 2",
"url": "http://google2.com"
},
"js": {
"initiator": "https://google2.com",
"url": "http://url.com"
}
}
]
Expected result:
[
{
"id": "js_1oc3uiteki22",
"tab": {
"title": "title 2",
"url": "http://google2.com"
},
"js": {
"initiator": "https://google2.com",
"url": "http://url.com"
}
}
]
Actually I have this following code which solves this problem but when I need to use that code 2 times in same js file I guess it's kinda conflicts and doesn't clean the duplicates well in second array.
function dupfix(arr) {
return arr.reverse().filter(val => {
if (!this.hasOwnProperty(val.js.url)) {
return this[val.js.url] = true
}
return false
}, {}).reverse()
}
file = dupfix(file)
So, how can I fix that code above or is there any other better methods to do that? Thanks.
I found that one really fast among other alternatives,
https://stackoverflow.com/a/61027136
function removeDuplicates(array, key) {
let lookup = {};
array.forEach(element => {
lookup[element[key]] = element
});
return Object.keys(lookup).map(key => lookup[key]);
};
removeDuplicates(array,'objectKey');
You can use like this to filter the duplicates.
const myArr=[
{
"id": "js_1oc3uiteki22",
"tab": {
"title": "title 1",
"url": "http://google.com"
},
"js": {
"initiator": "https://google.com",
"url": "http://url.com"
}
},
{
"id": "js_1oc3uiteki22",
"tab": {
"title": "title 2",
"url": "http://google2.com"
},
"js": {
"initiator": "https://google2.com",
"url": "http://url2.com"
}
},
{
"id": "js_1oc3uiteki23",
"tab": {
"title": "title 3",
"url": "http://google3.com"
},
"js": {
"initiator": "https://google3.com",
"url": "http://url3.com"
}
},
{
"id": "js_1oc3uiteki23",
"tab": {
"title": "title 4",
"url": "http://google4.com"
},
"js": {
"initiator": "https://google4.com",
"url": "http://url4.com"
}
}
]
function removeDuplicates(arr) {
let uniqueIds = [];
var result = arr.slice().reverse().filter(item => {
var isDuplicate = uniqueIds.includes(item.id);
if (!isDuplicate) {
uniqueIds.push(item.id);
return item;
}
});
return result;
}
console.log(removeDuplicates(myArr));
You can use hash grouping to uniquely identify objects:
const val = [{"id":"js_1oc3uiteki22","tab":{"title":"title 1","url":"http://google.com"},"js":{"initiator":"https://google.com","url":"http://url.com"}},{"id":"js_1oc3uiteki22","tab":{"title":"title 2","url":"http://google2.com"},"js":{"initiator":"https://google2.com","url":"http://url.com"}}];
const uniqs = val.reduce((r, item) => (r[item.js.url] = item, r), {});
const result = Object.values(uniqs);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0 }

Filter an array of objects with nested arrays based on another array

I've 2 different APIs. first one returns an array of event objects (this data set is growing and expected to be large). each event has a category array that has a list of strings. The other API returns an array of filter objects. each filter has a "name" property and an array of keywords. any keyword included in the categories array in any event should go under this filter name.
The ultimate goal is to have a list of filters on the screen and when a user click on a filter I should render all events under this filter.
Event Object Example:
{
"text": {
"headline": "Headline example",
"text": "event description "
},
"media": {
"url": "https://www.google.com/",
"caption": "",
"credit": ""
},
"categories": [
"National",
"Canada",
"British Columbia"
]
}
Filters Object Example:
{
"filters": [
{
"keywords": [
"Atlantic",
"New Brunswick",
"Newfoundland and Labrador",
"Prince Edward Island",
"Nova Scotia"
],
"name": "Atlantic"
},
{
"keywords": [
"ontario",
"Quebec"
],
"name": "Central Canada"
},
{
"keywords": [
"Manitoba",
"Saskatchewan",
"Alberta"
],
"name": "Prairie Provinces"
},
{
"keywords": [
"British Columbia"
],
"name": "West Coast"
},
{
"keywords": [
"Nunavut",
"Northwest Territories",
"Yukon Territory"
],
"name": "North"
},
{
"keywords": [
"National"
],
"name": "National"
}
]
}
After a couple of days working on it I came up with this solution.
function filterTimelineData(filtersObj, timelineData) {
if (!timelineData || !filtersObj) return [];
// create a new object with filters "name" as key;
const filters = Object.keys(filtersObj);
const filteredTimelineData = Object.keys(filtersObj).reduce((o, key) => ({ ...o, [key]: [] }), {});
const filteredData = timelineData.events.reduce((acc, current) => {
let filterMatch = false;
let filterMatchName = '';
for (let i = 0; i < filters.length; i++) {
filterMatch = current.categories.some(item => {
return filtersObj[filters[i]].includes(item.toLocaleLowerCase());
});
if (filterMatch && filterMatchName !== filters[i]) { // to avoid duplicated items with different categories under the same filter
filterMatchName = filters[i];
acc[filters[i]].push(current);
}
}
return acc;
}, filteredTimelineData);
return filteredData;
}
export function timelineFiltersObj(filters) {
const filtersObj = filters.filters.reduce((acc, current) => {
const filterName = current.name.replace(/ /g, '_').toLocaleLowerCase();
if (!acc.hasOwnProperty(filterName)) {
acc[filterName] = [];
}
acc[filterName] = [].concat(current.keywords.map(item => item.toLocaleLowerCase()));
return acc;
}, {});
return filtersObj;
}
Desired output:
An object or an array for all filters to be rendered on the screen
An object with filters name as a key and the value would be an array of events that has any keyword that matches any of this filter keywords
check this code example: link
My Questions:
Is there an easier/simpler way to solve this problem?
I'm passing "filteredTimelineData" object as initial value to .reduce function. Is this legitimate? I couldn't find any answers online to this question specifically.
from a time complexity prospective. will this code cause any memory issue if the dataset grows?
This is a simple way to get the above result. I am using JavaScript ES5 features in this solution which is supported by almost all the browsers except IE9
const filters = {
"filters": [
{
"keywords": [
"Atlantic",
"New Brunswick",
"Newfoundland and Labrador",
"Prince Edward Island",
"Nova Scotia"
],
"name": "Atlantic"
},
{
"keywords": [
"ontario",
"Quebec"
],
"name": "Central Canada"
},
{
"keywords": [
"Manitoba",
"Saskatchewan",
"Alberta"
],
"name": "Prairie Provinces"
},
{
"keywords": [
"British Columbia"
],
"name": "West Coast"
},
{
"keywords": [
"Nunavut",
"Northwest Territories",
"Yukon Territory"
],
"name": "North"
},
{
"keywords": [
"National"
],
"name": "National"
}
]
};
const timelineData = {
"events": [
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": ""
},
"categories": [
"New Brunswick"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": ""
},
"categories": [
"National"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": "https://youtu.be/poOO4GN3TN4"
},
"categories": [
"Northwest Territories"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": ""
},
"categories": [
"Ontario"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": ""
},
"categories": [
"National"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": "https://philanthropy.cdn.redcross.ca/timeline/July2020-3.jpg"
},
"categories": [
"British Columbia"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": ""
},
"categories": [
"Alberta"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": ""
},
"categories": [
"Prince Edward Island"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": ""
},
"categories": [
"National"
]
},
{
"text": {
"headline": "headline example",
"text": "event-descriprion"
},
"media": {
"url": ""
},
"categories": [
"National"
]
}
]
};
var categoriesToEventsMap = timelineData.events.reduce((res, event) => {
event.categories.forEach(c=> {
res = {
...res,
[c.toLowerCase()]: [...(res[c.toLowerCase()] || []), event]
}
});
return res;
}, {})
var result = filters.filters.reduce((acc, filter) => {
let events = []
const filterName = filter.name.replace(' ', '_').toLowerCase();
filter.keywords.forEach((key)=>{
events = [...events, ...(categoriesToEventsMap[key.toLowerCase()] || [])];
});
acc[filterName] = [...(acc[filterName] || []), ...events]
return acc;
}, {});
console.log(result);

Iterate and group the objects using map function

Check for the decimal id and group them accordingly.
Below are the sample and recommended JSON's
Sample JSON
{
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
Would like to iterate and Re-structure the above JSON into below recommended format.
Logic: Should check the id(with and without decimals) and group them based on the number.
For Example:
1, 1.1, 1.2.3, 1.4.5 => data1: [{id: 1},{id: 1.1}....]
2, 2.3, 2.3.4 => data2: [{id: 2},{id: 2.3}....]
3, 3.1 => data3: [{id: 3},{id: 3.1}]
Recommended JSON
{
"results": [
{
"data1": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
}
]
},
{
"data2": [
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
}
]
},
{
"data3": [
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
}
]
},
{
"data4": [
{
"name": "Download",
"id": "4.2"
}
]
}
]
}
I have tried the below solution but it doesn't group the object
var formatedJSON = [];
results.map(function(d,i) {
formatedJSON.push({
[data+i]: d
})
});
Thanks in advance.
You can use reduce like this. The idea is to create a key-value pair for each data1, data2 etc so that values in this object are the values you need in the final array. Then use Object.values to get those as an array.
const sampleJson = {"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]}
const grouped = sampleJson.results.reduce((a, v) => {
const key = `data${parseInt(v.id)}`;
(a[key] = a[key] || {[key]: []})[key].push(v);
return a;
},{});
console.log({results: Object.values(grouped)})
One liner / Code-golf:
let s={"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]},k;
console.log({results:Object.values(s.results.reduce((a,v)=>(k=`data${parseInt(v.id)}`,(a[k] = a[k]||{[k]:[]})[k].push(v),a),{}))})
Here you go:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
let newSet = new Set();
data.results.forEach(e => {
let key = e.id.substring(0, e.id.indexOf('.'));
console.log(key);
if (newSet.has(key) == false) {
newSet.add(key);
newSet[key] = [];
}
newSet[key].push(e.id);
});
console.log(newSet);
Here's how you'd do it:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
var newData = {
"results": {}
};
data.results.forEach(item => {
var num = item.id.slice(0, 1);
if (newData.results["data" + num]) {
newData.results["data" + num].push(item);
} else {
newData.results["data" + num] = [item];
}
})
data = newData;
console.log(data);
What this does is it iterates through each item in results, gets the number at the front of this item's id, and checks if an array of the name data-{num} exists. If the array exists, it's pushed. If it doesn't exist, it's created with the item.
let input = getInput();
let output = input.reduce((acc, curr)=>{
let {id} = curr;
let majorVersion = 'name' + id.split('.')[0];
if(!acc[majorVersion]) acc[majorVersion]= [];
acc[majorVersion].push(curr);
return acc;
},{})
console.log(output)
function getInput(){
return [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
One solution with RegEx for finer control as it would differentiate easily between 1 and 11.
Also this will make sure that even if the same version comes in end(say 1.9 in end) it will put it back in data1.
let newArr2 = ({ results }) =>
results.reduce((acc, item) => {
let key = "data" + /^(\d+)\.?.*/.exec(item.id)[1];
let found = acc.find(i => key in i);
found ? found[key].push(item) : acc.push({ [key]: [item] });
return acc;
}, []);

Adding object to parent array based on IDs using Lodash

So I'm having an issue - I'm getting some data from our internal API at work, but it's not in the correct format I need to do what I have to do, so I have to make some transformations.
For this, I decided to use Lodash, however I'm stuck now.
Basically, I'm working with orders, but some of the products are addons to a parent product. I've managed so far to separate these two types of products, but I don't know how I should go about adding an "addons" array as a child to the parent product with matching ID.
Here's a basic stripped example of the output I'd like:
{
"order": {
"orderLines: [
{
"orderId": "foo",
"addons" [
{
...
}
]
},
{
...
}
]
}
}
And here's my current code:
// TODO:
// Match addons to products based on "connectedTo" => "id", then add matching addons as a new array on parent object
// Base data
const data = {
"order": {
"shopOrderId": "19LQ89H",
"createDate": "2017-10-24T13:09:22.325Z",
"orderLines": [
{
"orderId": "19LQ89H",
"product": {
"productName": "Paintball",
},
"id": "59ef3b8036e16f1c84787c1f",
"stringId": "59ef3b8036e16f1c84787c1f"
},
{
"orderId": "19LQ89H",
"product": {
"productName": "Ølsmagning",
},
"id": "59ef3b8036e16f1c84787c20",
"stringId": "59ef3b8036e16f1c84787c20"
},
{
"orderId": "19LQ89H",
"product": {
"productName": "CD-indspilning",
},
"id": "59ef3b8136e16f1c84787c21",
"stringId": "59ef3b8136e16f1c84787c21"
},
{
"orderId": "19LQ89H",
"product": {
"productName": "Julefrokost",
},
"id": "59ef3b8236e16f1c84787c22",
"stringId": "59ef3b8236e16f1c84787c22"
},
{
"orderId": "19LQ89H",
"product": {
"productName": "Hummer Limousine",
},
"id": "59ef3b8236e16f1c84787c23",
"stringId": "59ef3b8236e16f1c84787c23"
},
{
"orderId": "19LQ89H",
"connectedTo": "59ef3b8236e16f1c84787c23",
"product": {
"productName": "Ekstra kørsel 400",
},
"id": "59ef3b8236e16f1c84787c24",
"stringId": "59ef3b8236e16f1c84787c24"
},
{
"orderId": "19LQ89H",
"connectedTo": "59ef3b8236e16f1c84787c23",
"product": {
"productName": "Drikkevarer",
},
"id": "59ef3b8236e16f1c84787c25",
"stringId": "59ef3b8236e16f1c84787c25"
},
{
"orderId": "19LQ89H",
"connectedTo": "59ef3b8236e16f1c84787c23",
"product": {
"productName": "Drikkevarer",
},
"id": "59ef3b8236e16f1c84787c26",
"stringId": "59ef3b8236e16f1c84787c26"
},
{
"orderId": "19LQ89H",
"connectedTo": "59ef3b8236e16f1c84787c22",
"product": {
"productName": "Snaps ad libitum",
},
"id": "59ef3b8236e16f1c84787c27",
"stringId": "59ef3b8236e16f1c84787c27"
}
],
"travelTimes": [
{
"id": "59ef3b8036e16f1c84787c1f-59ef3b8036e16f1c84787c20",
"partyPlanFromEventId": "59ef3b8036e16f1c84787c1f",
"partyPlanToEventId": "59ef3b8036e16f1c84787c20",
"start": "2017-11-15T17:02:59",
"end": "2017-11-15T17:30:00",
"travelTimeString": "27 min.",
"travelTimeMinutes": 28,
"exceedsAvailableTime": false
},
{
"id": "59ef3b8036e16f1c84787c20-59ef3b8136e16f1c84787c21",
"partyPlanFromEventId": "59ef3b8036e16f1c84787c20",
"partyPlanToEventId": "59ef3b8136e16f1c84787c21",
"start": "2017-11-15T19:52:12",
"end": "2017-11-15T20:00:00",
"travelTimeString": "8 min.",
"travelTimeMinutes": 8,
"exceedsAvailableTime": false
},
{
"id": "59ef3b8036e16f1c84787c20-59ef3b8236e16f1c84787c22",
"partyPlanFromEventId": "59ef3b8036e16f1c84787c20",
"partyPlanToEventId": "59ef3b8236e16f1c84787c22",
"start": "2017-11-15T12:30:00",
"end": "2017-11-15T13:00:00",
"travelTimeString": "8 min.",
"travelTimeMinutes": 8,
"exceedsAvailableTime": true
},
{
"id": "59ef3b8036e16f1c84787c20-59ef3b8236e16f1c84787c23",
"partyPlanFromEventId": "59ef3b8036e16f1c84787c20",
"partyPlanToEventId": "59ef3b8236e16f1c84787c23",
"start": "2017-11-15T08:30:00",
"end": "2017-11-15T09:00:00",
"travelTimeString": "3 min.",
"travelTimeMinutes": 4,
"exceedsAvailableTime": true
}
],
"id": "59ef3b8236e16f1c84787c28",
"stringId": "59ef3b8236e16f1c84787c28"
}
}
// Transform data
const travelTimes = data.order.travelTimes.map(item => _.omit(item, ['id']) )
const orderLines = _.merge(data.order.orderLines, travelTimes)
const order = _.omit(data.order, ['orderLines', 'travelTimes'])
const orders = _.assign(order, { orderLines })
const addonGroups = _.groupBy(order.orderLines, 'connectedTo')
const addons = _.omit(addonGroups, 'undefined')
const products = _.pick(addonGroups, 'undefined')
const productGroups = _.groupBy(products.undefined, 'stringId')
console.log(productGroups) // All parent products
console.log(addons) // All addon products
const arr1 = _.values(_.flatMap(productGroups))
const arr2 = _.values(_.flatMap(addons))
Code on Codepen.io
Any help is greatly appreciated!
Let me know if I need to explain in further detail.
Not sure if I understood correctly what the expected result is, but I gave it a try anyway.
const orderLines = _(data.order.orderLines)
.map(item => {
if (!item.connectedTo) return _.assignIn(item, { addons: [] });
const match = _.find(data.order.orderLines, { id: item.connectedTo });
match.addons = match.addons || [];
match.addons.push(item);
return null;
})
.compact()
.value();
Check the output here: https://codepen.io/andreiho/pen/YEzQRd?editors=0012

Filter method on multidimensional array

I have an id and i to filter a multidimensional array with these. My code is:
service.fakedata.map(f=>{
f.results.map(r=>{
r = r.filter(m=> m.rId !== id)
})
})
and my array is :
"services": [
{
"id": "1839f72e-fa73-47de-b119-49fb971a5730",
"name": "In I/O Route",
"url": "http://wwww.in.io/[param1]/[param2]",
"inputParams": [
{
"id": "e74a6229-4c08-43a1-961f-abeb887fa90e",
"name": "in1",
"datatype": "string"
},
{
"id": "e74a6229-4c08-43a1-961f-abeb887fa90o",
"name": "in2",
"datatype": "string"
}
],
"isArrayResult": false,
"results": [
{
"id": "ef7c98db-9f12-45a8-b3fb-7d09a82abe3d",
"name": "out1",
"datatype": "string",
"fakedatatype": [
"address",
"city"
]
},
{
"id": "9b178ded-af27-43df-920f-daab5ad439b9",
"name": "out2",
"datatype": "string",
"fakedatatype": [
"internet",
"url"
]
}
],
"routeParameters": [
"param1",
"param2"
],
"fakedata": [
{
"id": "b0376694-9612-43d2-93ed-c74264df962e",
"url": "http://wwww.in.io/wood/good",
"params": [
{
"key": "param1",
"value": "wood"
},
{
"key": "param2",
"value": "good"
}
],
"inputParams": [
{
"iId":"e74a6229-4c08-43a1-961f-abeb887fa90e",
"key": "in1",
"value": "m"
},
{
"iId":"e74a6229-4c08-43a1-961f-abeb887fa90o",
"key": "in2",
"value": "z"
}
],
"results": [
{
"rId": "ef7c98db-9f12-45a8-b3fb-7d09a82abe3d",
"key": "out1",
"value": "result1",
"fakedatatype": [
"address",
"city"
]
},
{
"rId": "9b178ded-af27-43df-920f-daab5ad439b9",
"key": "out2",
"value": "result2",
"fakedatatype": [
"internet",
"url"
]
}
]
}
]
}
]
In this case filter is working (when I check with console.log) but it doesn't change fakedata array.
What was wrong with my code?
From https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
base on #H77 suggestion i change my code and now my code is look like this and everything work well
const s = service.fakedata.map(f=>{
f.results = f.results.map(r=>{
return r.filter(m=> m.rId !== id)
})
})

Categories