I have an array of objects with duplicates:
[
{
"code": "d1",
"title": "Title 1"
},
{
"code": "d2",
"title": "Title 2"
},
{
"code": "d3",
"title": "Title 3"
},
{
"code": "d4",
"title": "Title 4"
},
{
"code": "d4",
"title": "Title 4"
},
{
"code": "d3",
"title": "Title 3"
}
]
So i want the output to be having only the once which doesn't have duplicates included like below:
[
{
"code": "d1",
"title": "Title 1"
},
{
"code": "d2",
"title": "Title 2"
}
]
Any help would be appreciated, Thanks!
Find unique's values in an array.
const ressult = YourArray.filter(
(value, index, array) => array.findIndex((v) => v.code === value.code) === index
);
Here is one way of doing it:
const products=[
{
"code": "d1",
"title": "Title 1"
},
{
"code": "d2",
"title": "Title 2"
},
{
"code": "d3",
"title": "Title 3"
},
{
"code": "d4",
"title": "Title 4"
},
{
"code": "d4",
"title": "Title 4"
},
{
"code": "d3",
"title": "Title 3"
}
];
const res=Object.entries(products.reduce((a,c)=>{
(a[c.code+"|"+c.title]??=[]).push(c);
return a;
},{})).reduce((a,[k,v])=>{
if(v.length==1) a.push(v[0]);
return a;
},[]);
console.log(res);
My approach involves two .reduce() loops:
In the first one I generate an object that collects all elements of the original array behind a compound key made up of the properties of the elements.
the object is then converted into an array again with Object.entries()
and in a second .reduce() only those elements will be collected (i. e.: their first element) into the target array that have a length of 1
let val = [
{
"code": "d1",
"title": "Title 1"
},
{
"code": "d2",
"title": "Title 2"
},
{
"code": "d3",
"title": "Title 3"
},
{
"code": "d4",
"title": "Title 4"
},
{
"code": "d4",
"title": "Title 4"
},
{
"code": "d3",
"title": "Title 3"
}
];
let distinctVal = getDistincts(val);
function getDistincts(val){
let obj={};
for (let i = 0; i < val.length; i++) {
obj[`${val[i]["code"]}`]=val[i]["title"];
}
return obj;
}
console.log(distinctVal);
Related
I need help, I got stuck on objects with multiple nested arrays. I have a json file which consists of object, that holds array of objects, and these objects have another array of objects in them. What is the best way to loop through it?
fetch("data.json").then((response) => response.json()).then((data) => {
document.getElementById("main").innerHTML += `<h1>${data.name}</h1>`;
for (i = 0; i < data.topics.length; i++) {
document.getElementById("main").innerHTML += `
<div>
<h2>${data.topics[i].title}</h2>
<ul id="programs">
<li>programs title here</li>
<li>programs title here</li>
<li>programs title here</li>
<ul>
</div>
`;
}});
json data looks like this:
{
"name": "Open Day Event",
"date": "July 7",
"topics": [
{
"title": "Engineering",
"id": 1,
"description": "some text here",
"programs": [
{
"title": "Some title",
"id": 1,
"description": "Some description",
"price": 30
},
{
"title": "Some title",
"id": 2,
"description": "Some description",
"price": 30
},
{
"title": "Some title",
"id": 3,
"description": "Some description",
"price": 30
}
]
},
{
"title": "History",
"id": 2,
"description": "some text here",
"programs": [
{
"title": "Some title",
"id": 1,
"description": "Some description",
"price": 30
},
{
"title": "Some title",
"id": 2,
"description": "Some description",
"price": 30
},
{
"title": "Some title",
"id": 3,
"description": "Some description",
"price": 30
}
]
},
{
"title": "English",
"id": 3,
"description": "some text here",
"programs": [
{
"title": "Some title",
"id": 1,
"description": "Some description",
"price": 30
},
{
"title": "Some title",
"id": 2,
"description": "Some description",
"price": 30
},
{
"title": "Some title",
"id": 3,
"description": "Some description",
"price": 30
}
]
}
]
}
You can use Array.prototype.forEach()
let html = "";
data.topics.forEach(topic => {
html += `<h2>${topic.title}</h2> <ul>`;
topic.programs.forEach(program => {
html += `<li>${program.title}</li>`
});
html += `</ul>`
})
document.getElementById('main').innerHTML = html;
You can achieve that recursively and by iterating the nested array.
Demo :
const jsonObj = {
"name": "Open Day Event",
"date": "July 7",
"topics": [{
"title": "Engineering",
"id": 1,
"description": "some text here",
"programs": [{
"title": "Some title",
"id": 1,
"description": "Some description",
"price": 30
}, {
"title": "Some title",
"id": 2,
"description": "Some description",
"price": 30
}, {
"title": "Some title",
"id": 3,
"description": "Some description",
"price": 30
}]
}, {
"title": "History",
"id": 2,
"description": "some text here",
"programs": [{
"title": "Some title",
"id": 1,
"description": "Some description",
"price": 30
}, {
"title": "Some title",
"id": 2,
"description": "Some description",
"price": 30
}, {
"title": "Some title",
"id": 3,
"description": "Some description",
"price": 30
}]
}, {
"title": "English",
"id": 3,
"description": "some text here",
"programs": [{
"title": "Some title",
"id": 1,
"description": "Some description",
"price": 30
}, {
"title": "Some title",
"id": 2,
"description": "Some description",
"price": 30
}, {
"title": "Some title",
"id": 3,
"description": "Some description",
"price": 30
}]
}]
};
function createList(parent, array) {
array.forEach(function (o) {
var li = document.createElement("li"),
ul;
li.textContent = o.title;
parent.appendChild(li);
if (o.programs) {
ul = document.createElement("ul");
li.appendChild(ul);
createList(ul, o.programs);
}
});
}
createList(document.querySelector("ul"), jsonObj.topics);
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<ul></ul>
I have two arrays of objects that I need to combine where the nested ID (connect.id) of the second array matches the id of the first but can't see how to do it
can anyone help?
const arr1 = [
{ "id": 7619209572755, "title": "Title 1" },
{ "id": 7619209157372, "title": "Title 2" },
{ "id": 7619209921625, "title": "Title 3" }
];
const arr2 = [
{
"id": 7619217289192,
"connect": [
{ "id": 7619209157372, "title": "Title 1" }
],
"value": "1"
},
{
"id": 7619217242206,
"connect": [
{ "id": 7619209921625, "title": "Title 2" }
],
"value": "2"
}
];
const expectedResult = [
{ "id": 7619209572755, "title": "Title 1" },
{ "id": 7619209157372, "title": "Title 2", "value": "1" },
{ "id": 7619209921625, "title": "Title 3", "value": "2" }
]
Using Array#reduce, iterate over arr2 to map every connect element's id with the its object's value in a Map
Using Array#map, iterate over arr1, if an element's id is in the map, set its value
const
arr1 = [ { "id": 7619209572755, "title": "Title 1" }, { "id": 7619209157372, "title": "Title 2" }, { "id": 7619209921625, "title": "Title 3" } ],
arr2 = [
{
"id": 7619217289192,
"connect": [ { "id": 7619209157372, "title": "Title 1" } ],
"value": "1",
},
{
"id": 7619217242206,
"connect": [ { "id": 7619209921625, "title": "Title 2" } ],
"value": "2",
}
];
const connectValueMap = arr2.reduce((map, { connect = [], value}) => {
connect.forEach(({ id }) => map.set(id, value));
return map;
}, new Map);
const merged = arr1.map(e => {
const value = connectValueMap.get(e.id);
if(value) e.value = value;
return e;
});
console.log(merged);
I have a nested object array like below,
data = [
{
"field": "A",
"items": [
{
"Id": 001,
"ItemDescription": "item 1"
}
]
},
{
"field": "A",
"items": [
{
"Id": 002,
"ItemDescription": "item 2"
},
{
"Id": 003,
"ItemDescription": "item 3"
},
{
"Id": 004,
"ItemDescription": "item 4"
}
]
}
]
I am trying to fetch only the inner object array from the object array.
I have tried different ways to fetch the inner object array from object array,
data.map((u,i) => u[i].map((a,b)=> a.items))
expected result:
data = [
{
"Id": 001,
"ItemDescription": "item 1"
},
{
"Id": 002,
"ItemDescription": "item 2"
},
{
"Id": 003,
"ItemDescription": "item 3"
},
{
"Id": 004,
"ItemDescription": "item 4"
}
]
You can use map and flat
let data = [
{
"field": "A",
"items": [
{
"Id": 001,
"ItemDescription": "item 1"
}
]
},
{
"field": "A",
"items": [
{
"Id": 002,
"ItemDescription": "item 2"
},
{
"Id": 003,
"ItemDescription": "item 3"
},
{
"Id": 004,
"ItemDescription": "item 4"
}
]
}
]
let result = data.map(d => d.items).flat();
console.log(result);
Output
Just use a single .map to get the values in the items array
let newArr = data.map((u,i) => u.items)
console.log(newArr)
and to return all the values in one single array use .flat
console.log(newArr.flat())
I have the following array:
const items = [
{
"id": 1,
"name": "Menu 1",
"content": [
{
"id": 2,
"name": "Submenu 1 OF 1",
"url": "teste"
}
]
},
{
"id": 3,
"name": "Menu 2",
"content": [
{
"id": 4,
"name": "Submenu 1 OF 2",
"url": "teste"
},
{
"id": 5,
"name": "Submenu 2 OF 2",
"content": [
{
"id": 6,
"name": "Sub submenu 1 OF 2",
"url": "teste"
},
{
"id": 7,
"name": "Sub submenu 2 OF 2",
"url": "teste"
},
]
}
]
}
]
I need a function that given the id gets the closest parent object. For example, if I give the id 2 it returns {"id: 1, "name": "Menu 1", "content": [...]}. If I give the id 6 it returns {"id": 5, "name": "Submenu 2 OF 2", content: [...]}.
I have tried but i can only get the top-level parent and not the closest one.
EDIT: the code that i have tested so far:
let findDeep = function(data, id) {
return data.find(function(e) {
if(e.id == id) return e;
else if(e.content) return findDeep(e.content, id);
}
})
You can use a recursive depth-first search:
function findParent(items, id, parent=null) {
for (let item of items) {
let res = item.id === id ? parent
: item.content && findParent(item.content, id, item);
if (res) return res;
}
}
// demo: find parent of id=6 in example tree:
const items = [{"id": 1,"name": "Menu 1","content": [{"id": 2,"name": "Submenu 1 OF 1","url": "teste"}]},{"id": 3,"name": "Menu 2","content": [{"id": 4,"name": "Submenu 1 OF 2","url": "teste"},{"id": 5,"name": "Submenu 2 OF 2","content": [{"id": 6,"name": "Sub submenu 1 OF 2","url": "teste"},{"id": 7,"name": "Sub submenu 2 OF 2","url": "teste"},]}]}]
console.log(findParent(items, 6));
You can do this with a recursive function that checks each child and returns the parent if the id matches:
const findParent = (id, obj) => {
for (const child of obj.content) {
if (child.id === id) return obj;
if (!child.content) continue;
const found = findParent(id, child);
if (found) return found;
}
return undefined;
}
const items = {content: [{
"id": 1,
"name": "Menu 1",
"content": [{
"id": 2,
"name": "Submenu 1 OF 1",
"url": "teste"
}]
},
{
"id": 3,
"name": "Menu 2",
"content": [{
"id": 4,
"name": "Submenu 1 OF 2",
"url": "teste"
},
{
"id": 5,
"name": "Submenu 2 OF 2",
"content": [{
"id": 6,
"name": "Sub submenu 1 OF 2",
"url": "teste"
},
{
"id": 7,
"name": "Sub submenu 2 OF 2",
"url": "teste"
},
]
}
]
}
]
}
console.log(findParent(2, items));
console.log(findParent(6, items));
I have a nested array of objects and want to get only the child property elements of an array with the title of the parent element prepended to the title in the child. This is just an example and the actual data will include a unique children property in separate indices in the array.
I would like to implement flatMap in my solution instead of using flattenDeep and map from lodash. Please advice.
const headers = [{
"id": "name1",
"title": "Name 1",
"children": [{
"title": "Children 1",
"child": [{
"title": "Child 1",
"onClick": "child1Click"
}, {
"title": "Child 2",
"onClick": "child2Click"
}]
}, {
"title": "CHildren 2",
"child": [{
"title": "Child 3",
"id": "child3Click"
}, {
"title": "Child 4",
"id": "child4Click"
}]
}]
}, {
"id": "name2",
"title": "Name 2",
"children": [{
"title": "Children 3",
"child": [{
"title": "Child 5",
"onClick": "child5Click"
}, {
"title": "Child 6",
"onClick": "child6Click"
}]
}, {
"title": "CHildren 4",
"child": [{
"title": "Child 7",
"id": "child7Click"
}, {
"title": "Child 8",
"id": "child8Click"
}]
}]
}, {
"id": "name3",
"title": "Name 3"
}, {
"id": "name4",
"title": "Name 4"
}]
console.log(_.flattenDeep(_.map(_.flattenDeep(_.compact(_.map(headers, item => item.children))), item => _.map(item.child, child => {
return {
...child,
title: `${item.title} ${child.title}`
}
}))))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
The output I expect is
[
{
"title": "Children 1 Child 1",
"onClick": "child1Click"
},
{
"title": "Children 1 Child 2",
"onClick": "child2Click"
},
{
"title": "CHildren 2 Child 3",
"id": "child3Click"
},
{
"title": "CHildren 2 Child 4",
"id": "child4Click"
},
{
"title": "Children 3 Child 5",
"onClick": "child5Click"
},
{
"title": "Children 3 Child 6",
"onClick": "child6Click"
},
{
"title": "CHildren 4 Child 7",
"id": "child7Click"
},
{
"title": "CHildren 4 Child 8",
"id": "child8Click"
}
]
Any help is greatly appreciated. Thanks
You can solve this with just reduce and two inner forEach loops for children and child.
const headers = [{"id":"name1","title":"Name 1","children":[{"title":"Children 1","child":[{"title":"Child 1","onClick":"child1Click"},{"title":"Child 2","onClick":"child2Click"}]},{"title":"CHildren 2","child":[{"title":"Child 3","id":"child3Click"},{"title":"Child 4","id":"child4Click"}]}]},{"id":"name2","title":"Name 2","children":[{"title":"Children 3","child":[{"title":"Child 5","onClick":"child5Click"},{"title":"Child 6","onClick":"child6Click"}]},{"title":"CHildren 4","child":[{"title":"Child 7","id":"child7Click"},{"title":"Child 8","id":"child8Click"}]}]},{"id":"name3","title":"Name 3"},{"id":"name4","title":"Name 4"}]
const result = headers.reduce((r, {children}) => {
children && children.forEach(({title: pTitle, child}) => {
child && child.forEach(({title, ...rest}) => r.push({
title: `${pTitle} ${title}`,
...rest
}))
})
return r;
}, [])
console.log(result)