This question already has answers here:
How to filter object array based on attributes?
(21 answers)
Closed 3 years ago.
Say I have an array of music
The code below returns all the titles for all genres. However, I only want the title names for songs in the Country genre.
const music= [{
"title": "Cheats",
"year": 2018,
"cast": ["Jane Rhee", "Kacey Brown"],
"genres": ["Country"]
}, {
"title": "Road",
"year": 2018,
"cast": ["Jeff Bates", "Alan Walker", "Cindy Bates"],
"genres": ["Country"]
}, {
"title": "Trail Down",
"year": 2018,
"cast": ["Ken Clemont"],
"genres": ["Jazz"]
}, {
"title": "Way Down",
"year": 2018,
"cast": ["Denzel Harr", "Dan Smith", "Lee Kyle", "Nate Hill"],
"genres": ["Pop"]
}, {
"title": "Fountain",
"year": 2018,
"cast": ["Brad Smith", "Rosa King"],
"genres": ["Rock"]
}, {
"title": "Gold Bells",
"year": 2018,
"cast": ["Paisley John"],
"genres": ["Blues"]
}, {
"title": "Mountain Curve",
"year": 2018,
"cast": ["Michael Johnson"],
"genres": ["Country"]
}, {
"title": "Arabella",
"year": 2018,
"cast": [],
"genres": ["Jazz"]
}, {
"title": "Curved",
"year": 2018,
"cast": ["Brett Shay"],
"genres": ["Country"]
}];
let songs = [];
for (var i = 0; i < music.length; i++) {
songs.push(music[i].title);
}
console.log(songs);
.filter the array by whether Country is included in the genres, then .map to the titles:
const music=[{title:"Cheats",year:2018,cast:["Jane Rhee","Kacey Brown"],genres:["Country"]},{title:"Road",year:2018,cast:["Jeff Bates","Alan Walker","Cindy Bates"],genres:["Country"]},{title:"Trail Down",year:2018,cast:["Ken Clemont"],genres:["Jazz"]},{title:"Way Down",year:2018,cast:["Denzel Harr","Dan Smith","Lee Kyle","Nate Hill"],genres:["Pop"]},{title:"Fountain",year:2018,cast:["Brad Smith","Rosa King"],genres:["Rock"]},{title:"Gold Bells",year:2018,cast:["Paisley John"],genres:["Blues"]},{title:"Mountain Curve",year:2018,cast:["Michael Johnson"],genres:["Country"]},{title:"Arabella",year:2018,cast:[],genres:["Jazz"]},{title:"Curved",year:2018,cast:["Brett Shay"],genres:["Country"]}];
const countryTitles = music
.filter(({ genres }) => genres.includes('Country'))
.map(({ title }) => title);
console.log(countryTitles)
If you want to do it while only iterating over the dataset once, use reduce instead:
const music=[{title:"Cheats",year:2018,cast:["Jane Rhee","Kacey Brown"],genres:["Country"]},{title:"Road",year:2018,cast:["Jeff Bates","Alan Walker","Cindy Bates"],genres:["Country"]},{title:"Trail Down",year:2018,cast:["Ken Clemont"],genres:["Jazz"]},{title:"Way Down",year:2018,cast:["Denzel Harr","Dan Smith","Lee Kyle","Nate Hill"],genres:["Pop"]},{title:"Fountain",year:2018,cast:["Brad Smith","Rosa King"],genres:["Rock"]},{title:"Gold Bells",year:2018,cast:["Paisley John"],genres:["Blues"]},{title:"Mountain Curve",year:2018,cast:["Michael Johnson"],genres:["Country"]},{title:"Arabella",year:2018,cast:[],genres:["Jazz"]},{title:"Curved",year:2018,cast:["Brett Shay"],genres:["Country"]}];
const countryTitles = music
.reduce((a, { genres, title }) => {
if (genres.includes('Country')) {
a.push(title)
}
return a;
}, []);
console.log(countryTitles)
Try this:
let songs = [];
for (var i = 0; i < music.length; i++) {
if(music[i].genres == "Country"){ // if music genres equal to "country"
songs.push(music[i].title);
}
}
// output : Cheats,Road,Mountain Curve,Curved
Related
I'm doing a search filter. I need to return the entire object containing the given actor by the user. I can find the actor, but I'm not sure how to return the object where the actor is.
JSON file:
{
"title": "American Assassin",
"year": 2017,
"cast": [
"Dylan O'Brien",
"Michael Keaton",
"Sanaa Lathan",
"Shiva Negar",
"Taylor Kitsch"
],
"genres": []
},
{
"title": "Mother!",
"year": 2017,
"cast": [
"Jennifer Lawrence",
"Javier Bardem",
"Michelle Pfeiffer",
"Domhnall Gleeson",
"Ed Harris",
"Kristen Wiig"
],
"genres": []
}
My filter function:
checkCast(allMovies) {
return filter(allMovies, (movie) => {
const actor = filter(movie.cast, (actor) => {
return actor.toLowerCase().includes(this.search.cast.toLowerCase())
})
console.log(actor)
return actor
});
}
Hope everything is clear.
You need to filter the allMovies array by looking for an actor in the case array. Use Array.some() (or lodash _.some()) to return true if a matching actor is found.
const search = { cast: 'bardem' };
function checkCast(allMovies) {
return allMovies.filter(movie =>
movie.cast.some(actor =>
actor.toLowerCase().includes(search.cast.toLowerCase())
)
);
}
const allMovies = [{"title":"American Assassin","year":2017,"cast":["Dylan O'Brien","Michael Keaton","Sanaa Lathan","Shiva Negar","Taylor Kitsch"],"genres":[]},{"title":"Mother!","year":2017,"cast":["Jennifer Lawrence","Javier Bardem","Michelle Pfeiffer","Domhnall Gleeson","Ed Harris","Kristen Wiig"],"genres":[]}]
const result = checkCast(allMovies)
console.log(result)
You can use array#find with array#includes to check if cast of movie include an actor.
const movies = [{ "title": "American Assassin", "year": 2017, "cast": [ "Dylan O'Brien", "Michael Keaton", "Sanaa Lathan", "Shiva Negar", "Taylor Kitsch" ], "genres": [] }, { "title": "Mother!", "year": 2017, "cast": [ "Jennifer Lawrence", "Javier Bardem", "Michelle Pfeiffer", "Domhnall Gleeson", "Ed Harris", "Kristen Wiig" ], "genres": [] }],
actor = 'Ed Harris',
movie = movies.find(({cast}) => cast.includes(actor));
console.log(movie);
You can also do use convert actor and cast name to lower case to compare using array#find and array#some.
const movies = [{ "title": "American Assassin", "year": 2017, "cast": [ "Dylan O'Brien", "Michael Keaton", "Sanaa Lathan", "Shiva Negar", "Taylor Kitsch" ], "genres": [] }, { "title": "Mother!", "year": 2017, "cast": [ "Jennifer Lawrence", "Javier Bardem", "Michelle Pfeiffer", "Domhnall Gleeson", "Ed Harris", "Kristen Wiig" ], "genres": [] }],
actor = 'ed harris',
movie = movies.find(({cast}) => cast.some(member => member.toLowerCase() === actor.toLowerCase()));
console.log(movie);
I'll freely admit that Javascript is not my strongest language, and React Native is very new, so, there may be an obviously easy way to do this that I'm not seeing.
I've got an API that presents some transaction data in a simple structure:
[
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
I want to present this data using a SectionList component, with the transactions in sections by date. My (likely crude) attempt to solve this was going to be to transform this data into the following structure:
[
{
"date": "2021-09-10",
"transactions": [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
}
]
},
{
"date": "2021-09-09",
"transactions": [
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
}
]
},
{
"date": "2021-09-07",
"transactions": [
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
}
]
But I'm honestly lost as to how to transform this data (or if there's a better way to solve this problem). I started by using Lodash's groupBy function, which seemed promising, but it looks like SectionList doesn't want an object, it wants an array.
Transforming the output of groupBy into an array straight off drops the keys and I've got grouped data but no clear value for the section header.
Again, there's probably some deviously simple way to address this, data comes in as a flat array all the time. I appreciate any guidance, assistance, or examples anybody can point me to.
const input = [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
const result = input.reduce((accum, current)=> {
let dateGroup = accum.find(x => x.date === current.date);
if(!dateGroup) {
dateGroup = { date: current.date, transactions: [] }
accum.push(dateGroup);
}
dateGroup.transactions.push(current);
return accum;
}, []);
console.log(result)
Given an array, whenever your result is expecting to have same number of elements, use map, but since your result has different number of elements, use reduce as shown above. The idea is by having reduce, loop over each element, see if you can find the element, and push the current element into the list
The lodash groupBy just helps you with group data, you should process grouped data by converting it into your format.
const input = [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
];
const groupedArray = _.groupBy(input, "date");
let result = [];
for (const [key, value] of Object.entries(groupedArray)) {
result.push({
'date': key,
'transactions': value
})
}
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
simply
const data =
[ { id: 1, title: 'Apple Store', date: '2021-09-10', amount: '$100.00' }
, { id: 41, title: 'Zulauf, Walter and Metz', date: '2021-09-10', amount: '$14.00' }
, { id: 9, title: 'Aufderhar PLC', date: '2021-09-09', amount: '$78.00' }
, { id: 10, title: 'Bayer and Sons', date: '2021-09-07', amount: '$67.00' }
]
const res = Object.entries(data.reduce((r,{id,title,date,amount})=>
{
r[date] = r[date] ?? []
r[date].push({id,title,date,amount})
return r
},{})).map(([k,v])=>({date:k,transactions:v}))
console.log( res )
.as-console-wrapper { max-height: 100% !important; top: 0 }
With lodash you can group by the date then map to the required form:
const input = [{"id":1,"title":"Apple Store","date":"2021-09-10","amount":"$100.00"},{"id":41,"title":"Zulauf, Walter and Metz","date":"2021-09-10","amount":"$14.00"},{"id":9,"title":"Aufderhar PLC","date":"2021-09-09","amount":"$78.00"},{"id":10,"title":"Bayer and Sons","date":"2021-09-07","amount":"$67.00"}];
const result = _.map(
_.groupBy(input, 'date'),
(transactions, date) => ({ date, transactions })
)
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
you could use loadash
var result = _(data)
.groupBy(item => item.date)
.map((value, key) => ({date: key, transactions: value}))
.value();
I am reading a simple data set from a data.txt file. I would like to take this data and transform it into a specific object as per my example below. I have managed to get it into a somewhat usable JSON object but this is not ideal. I have included an example of the desired object.
Here is my app.js file:
let output = fs.readFileSync('./data.txt', 'UTF8')
.trim()
.split('\r\n')
.map((line) => line.split(';'))
.reduce((customers, line) => {
customers.push({
name: line[0],
product: [{
item: line[1],
serial: line[2],
year: line[3]
}]
})
return customers
}, [])
console.log(JSON.stringify(output, null, 2))
This currently the above NodeJs code returns the following array object:
[
{
"name": "Nancy",
"product": [
{
"item": "Macbook Pro",
"serial": "A34D05980FCD4303",
"year": "2019"
}
]
},
{
"name": "Nancy",
"product": [
{
"item": "iPad",
"serial": "O0403X3028423C92",
"year": "2015"
}
]
},
{
"name": "Nancy",
"product": [
{
"item": "iPhone",
"serial": "X3830238S3309230",
"year": "2017"
}
]
},
{
"name": "John",
"product": [
{
"item": "Macbook Pro",
"serial": "X2020J393983H380",
"year": "2013"
}
]
},
{
"name": "John",
"product": [
{
"item": "iPhone",
"serial": "X38320093X032309",
"year": "2015"
}
]
},
{
"name": "fluffikins",
"product": [
{
"item": "iMac",
"serial": "F392D392033X3232",
"year": "2013"
}
]
},
{
"name": "fluffikins",
"product": [
{
"item": "iPad",
"serial": "FE322230D3223S21",
"year": "2011"
}
]
}
]
What I am trying to do is get the below object returned - ideally still following the same functional approach:
[
{
"name": "Nancy",
"product": [
{
"item": "Macbook Pro",
"serial": "A34D05980FCD4303",
"year": "2019"
},
{
"item": "iPad",
"serial": "O0403X3028423C92",
"year": "2015"
},
{
"item": "iPhone",
"serial": "X3830238S3309230",
"year": "2017"
}
]
},
{
"name": "John",
"product": [
{
"item": "Macbook Pro",
"serial": "X2020J393983H380",
"year": "2013"
},
{
"item": "iPhone",
"serial": "X38320093X032309",
"year": "2015"
}
]
},
{
"name": "fluffikins",
"product": [
{
"item": "iMac",
"serial": "F392D392033X3232",
"year": "2013"
},
{
"item": "iPad",
"serial": "FE322230D3223S21",
"year": "2011"
}
]
}
]
Here is my mock data set that lives in data.txt
Nancy;Macbook Pro;A34D05980FCD4303;2019
Nancy;iPad;O0403X3028423C92;2015
Nancy;iPhone;X3830238S3309230;2017
John;Macbook Pro;X2020J393983H380;2013
John;iPhone;X38320093X032309;2015
fluffikins;iMac;F392D392033X3232;2013
fluffikins;iPad;FE322230D3223S21;2011
Instead of an array you can use Map in reduce as accumulator, use name as key in Map and club value of all keys, finally just get the values Map to get desired output
const data = `Nancy;Macbook Pro;A34D05980FCD4303;2019
Nancy;iPad;O0403X3028423C92;2015
Nancy;iPhone;X3830238S3309230;2017
John;Macbook Pro;X2020J393983H380;2013
John;iPhone;X38320093X032309;2015
fluffikins;iMac;F392D392033X3232;2013
fluffikins;iPad;FE322230D3223S21;2011`
const final = data.split('\n')
.map(v => v.split(';'))
.reduce((op, [name, item, serial, year]) => {
let obj = { item, serial, year }
if (op.has(name)) {
op.get(name).products.push(obj)
} else{
op.set(name,{name, products:[obj]})
}
return op
}, new Map())
console.log([...final.values()])
Here is a "functional version" that utilizes a Map to find duplicates in O(1):
(map => (
fs.readFileSync('./data.txt', 'UTF8')
.trim()
.split('\r\n')
.map((line) => line.split(';'))
.forEach(([name, item, serial, year]) =>
map.has(name)
? map.get(name).product.push({ item, serial, year })
: map.set(name, { name, product: [{ item, serial, year }] })
),
[...map.values()]
)(new Map)
But seriously, whats so bad about imperative style?:
const customers = new Map;
const entries = fs.readFileSync('./data.txt', 'UTF8')
.trim()
.split('\r\n');
for(const entry of entries) {
const [name, item, serial, year] = entry.split(";");
const product = { item, serial, year };
if(customers.has(name)) {
customers.get(name).product.push(product);
} else customers.set(name, { name, product: [product] });
}
const result = [...customers.values()];
You can modify the .reduce function to only add a new item to the array if there isn't one with that name. If there is, just add the product to that item's product array.
const data = `Nancy;Macbook Pro;A34D05980FCD4303;2019
Nancy;iPad;O0403X3028423C92;2015
Nancy;iPhone;X3830238S3309230;2017
John;Macbook Pro;X2020J393983H380;2013
John;iPhone;X38320093X032309;2015
fluffikins;iMac;F392D392033X3232;2013
fluffikins;iPad;FE322230D3223S21;2011`;
const result = data.trim()
.split('\n')
.map((line) => line.split(';'))
.reduce((customers, line) => {
const product = {
item: line[1],
serial: line[2],
year: line[3]
};
const customer = customers.find(({
name
}) => name === line[0]);
if (customer) {
customer.product.push(product);
} else {
customers.push({
name: line[0],
product: [product]
});
}
return customers
}, []);
console.log(result);
From the following array:
var arr = [{ "Year": 2019, "Title": "Sample1", "Sum": 1020000.0, "Budget":0},
{ "Year": 2019, "Title": "Sample2", "Sum": 2546658.0, "Budget":100},
{ "Year": 2019, "Title": "Sample3", "Sum": 1020000.0, "Budget":1000},
{ "Year": 2020, "Title": "Sample1", "Sum": 3472000.0, "Budget":100},
{ "Year": 2020, "Title": "Sample2", "Sum": 1020000.0, "Budget":10},
{ "Year": 2020, "Title": "Sample3", "Sum": 2452000.0, "Budget":50},
{ "Year": 2021, "Title": "Sample1", "Sum": 1000.0, "Budget":100},
{ "Year": 2021, "Title": "Sample2", "Sum": 119000.0, "Budget":10},
{ "Year": 2021, "Title": "Sample3", "Sum": 234000.0, "Budget":50}]
]
I need to change this into a single year per row, were the value of each "Title" has an entry with its "Sum" value and the Budget values should be aggregated together ie.
[{ "Year": 2019, "Sample1": 1020000.0, "Sample2":2546658.0, "Sample3":1020000.0 , "Budget":1100},{ etc]
My platform does not support ES6, through answers from an earlier post I have used .reduce as follows to get most of the way:
var res = arr.reduce(function(acc, curr) {
acc[curr.Year] = acc[curr.Year];
acc[curr.Year] = acc[curr.Year] || { Year: curr.Year } ;
acc[curr.Year][curr.Title] = curr.Sum;
return acc;
res = Object.keys(res).map(function(key) {
return res[key];
});
This produces:
[{ "Year": 2019, "Sample1": 1020000.0, "Sample2":2546658.0, "Sample3":1020000.0 },
{ "Year": 2020, "Sample2": 3472000.0, "Sample2":1020000.0, "Sample3":2452000.0},
{ "Year": 2021, "Sample3": 1000.0, "Sample2":119000.0, "Sample3":234000.0}]
But I cannot find a way to also sum the Budget figures together and add it to the same entry. I suspect I need to perform a separate reduce function on a duplicate array and push the result into the res array using the forEach loop with Year as the key. Can anyone see a way of doing this in the same reduce function?
When initializing a Year object in the reduce callback, also initialize a Budget property to 0. Then, on each iteration for that year, add to the budget property in addition to setting the Sample property:
var arr = [{ "Year": 2019, "Title": "Sample1", "Sum": 1020000.0, "Budget":0},
{ "Year": 2019, "Title": "Sample2", "Sum": 2546658.0, "Budget":100},
{ "Year": 2019, "Title": "Sample3", "Sum": 1020000.0, "Budget":1000},
{ "Year": 2020, "Title": "Sample1", "Sum": 3472000.0, "Budget":100},
{ "Year": 2020, "Title": "Sample2", "Sum": 1020000.0, "Budget":10},
{ "Year": 2020, "Title": "Sample3", "Sum": 2452000.0, "Budget":50},
{ "Year": 2021, "Title": "Sample1", "Sum": 1000.0, "Budget":100},
{ "Year": 2021, "Title": "Sample2", "Sum": 119000.0, "Budget":10},
{ "Year": 2021, "Title": "Sample3", "Sum": 234000.0, "Budget":50}
]
var res = arr.reduce(function(acc, curr) {
acc[curr.Year] = acc[curr.Year] || { Year: curr.Year, Budget: 0 } ;
// ^^^^^^^^^
acc[curr.Year][curr.Title] = curr.Sum;
acc[curr.Year].Budget += curr.Budget;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return acc;
}, {});
var output = Object.keys(res).map(function(key) {
return res[key];
});
console.log(output);
Note that the line in your original code
acc[curr.Year] = acc[curr.Year];
doesn't accomplish anything at all - you may omit it entirely.
You could consider using Babel and polyfills, allowing you to write code in the latest and greatest version of the language, while preserving compatibility for obsolete browsers, in which case, the code could be prettified to:
var arr=[{"Year":2019,"Title":"Sample1","Sum":1020000.0,"Budget":0},{"Year":2019,"Title":"Sample2","Sum":2546658.0,"Budget":100},{"Year":2019,"Title":"Sample3","Sum":1020000.0,"Budget":1000},{"Year":2020,"Title":"Sample1","Sum":3472000.0,"Budget":100},{"Year":2020,"Title":"Sample2","Sum":1020000.0,"Budget":10},{"Year":2020,"Title":"Sample3","Sum":2452000.0,"Budget":50},{"Year":2021,"Title":"Sample1","Sum":1000.0,"Budget":100},{"Year":2021,"Title":"Sample2","Sum":119000.0,"Budget":10},{"Year":2021,"Title":"Sample3","Sum":234000.0,"Budget":50}]
const output = Object.values(arr.reduce((a, { Year, Title, Sum, Budget }) => {
a[Year] = a[Year] || { Year, Budget: 0 };
a[Year][Title] = Sum;
a[Year].Budget += Budget;
return a;
}, {}));
console.log(output);
This question already has answers here:
How can I group an array of objects by key?
(32 answers)
Closed 3 years ago.
I'm trying to create a navigational menu out of some data. In order to do this I need to manipulate the data into an object of arrays. I am attempting to do this using map(), I've gotten to the point of making the keys of the object and a corresponding value, however, I don't know how to handle the multiple titles under it's corresponding year. Any help would be greatly appreciated.
const data = [
{
"fields": {
"title": "Frozen Thorns",
"year": 2017,
}
},
{
"fields": {
"title": "The Professional Years",
"year": 2018,
}
},
{
"fields": {
"title": "Green Nothing",
"year": 2018,
}
},
{
"fields": {
"title": "The Next Voyage",
"year": 2018,
}
},
{
"fields": {
"title": "Smooth Sorcerer",
"year": 2019,
}
},
{
"fields": {
"title": "Azure Star",
"year": 2019,
}
}]
const menu = Object.assign({}, ...data.map(item => ({[item.fields.year]: item.fields.title})));
// OUTPUT
// {
// 2017: "Frozen Thorns",
// 2018: "The Next Voyage",
// 2019: "Azure Star"
// }
// DESIRED OUTPUT
// {
// 2017: ["Frozen Thorns"],
// 2018: ["The Professional Years", "Green Nothing", "The Next Voyage"],
// 2019: ["Smooth Sorcerer", "Azure Star"]
// }
The general rule is that if you want to keep the same shape as your original array, then you use map, but if you want to turn it into a smaller shape you use the appropriately named reduce. Take a look at this.
const data = [
{
"fields": {
"title": "Frozen Thorns",
"year": 2017,
}
},
{
"fields": {
"title": "The Professional Years",
"year": 2018,
}
},
{
"fields": {
"title": "Green Nothing",
"year": 2018,
}
},
{
"fields": {
"title": "The Next Voyage",
"year": 2018,
}
},
{
"fields": {
"title": "Smooth Sorcerer",
"year": 2019,
}
},
{
"fields": {
"title": "Azure Star",
"year": 2019,
}
}];
const menu = data.reduce((accumulator, currentValue) => {
accumulator[currentValue.fields.year] = (accumulator[currentValue.fields.year] || []).concat(currentValue.fields.title);
return accumulator;
}, {});
console.log(menu);