Remove duplicates within the map function - javascript

I want to remove duplicates within the map function and I have looked through the different posts on the internet but I am still not finding the solution.
The JSON:
"results": [
{
"data": {
"labels": {
"results": [
{
"name": "tom"
}
]
}
}
},
{
"data": {
"labels": {
"results": [
{
"name": "jerry"
}
]
}
}
},
{
"data": {
"labels": {
"results": [
{
"name": "tom"
}
]
}
}
}
]
The code:
obj.results.map((items) => {
if (items.data.labels.results.length) {
items.data.labels.results.map((result) => {
console.log(result.name);
});
}
});
Result
tom
jerry
tom
Expected Result
tom
jerry
Tried this solution but didn't work
obj.results.map((items) => {
if (items.data.label.results.length) {
items.data.label.results.map((result) => {
console.log(Array.from(new Set(result.name)));
});
}
});
Result from above code
[ 't', 'o', 'm' ]
[ 'j', 'e', 'r', 'r', 'y' ]
[ 't', 'o', 'm' ]

I would use reduce since it is perfect for iterating an array with an accumulative value. In this case, an object.
const x = [{
"data": {
"results": [{
"name": "tom"
}]
}
},
{
"data": {
"results": [{
"name": "jerry"
}]
}
},
{
"data": {
"results": [{
"name": "tom"
}]
}
}
]
var result = Object.values(x.reduce(function(acc, item) {
var name = item.data.results[0].name
// acc[name] = item;
acc[name] = name;
return acc;
}, {}))
console.log(result)

you can achieve this using flatMap to get all name objects and then map to extract the name field. After that a Set to dedupe. [...new Set(..)] converts the Set back to an array
const results = [{
"data": {
"labels": {
"results": [{
"name": "tom"
}, {
"name": "another name"
}]
}
}
}, {
"data": {
"labels": {
"results": [{
"name": "jerry"
}]
}
}
}, {
"data": {
"labels": {
"results": [{
"name": "tom"
}]
}
}
}]
const res = [...new Set(results.flatMap(({data:{labels: {results}}}) => results).map(({name}) => name))]
//alternative
//const res = [...new Set(results.map(({data:{labels: {results}}}) => results).flat().map(({name}) => name))]
console.log(res)

Related

How to create parent-child object from array of sibling objects and filter elements?

I'm trying to create this object:
const data = [
{
"javascript": [
{
"product": "1234",
},
{
"product": "4321",
}
]
},
{
"python": [
{
"product": "9876",
}
]
}
]
Here on code snippet is the original object I'm trying to parse:
const myData = [
{
"category": "javascript",
"product": "1234"
},
{
"category": "javascript",
"product": "4321"
},
{
"category": "python",
"product": "9876"
},
];
const mountCategories = (data) => {
const categoriesObj = data.map(value => value.category).filter((value, index, a) => a.indexOf(value) === index)
const categorizedData = categoriesObj.map((value) => {
return {
value: data.map(value => {
return {
product: value.product,
}
})
}
});
return (
categorizedData
)
}
console.log(mountCategories(myData))
I'm not being able to get the category key string to work. Also I need to figure how to filter the elements properly.
You can try using array.reduce:
const myData = [
{
"category": "javascript",
"product": "1234"
},
{
"category": "javascript",
"product": "4321"
},
{
"category": "python",
"product": "9876"
},
];
let result = myData.reduce((acc,current) => {
let prev = acc.find(doc => doc[current.category]);
if(!prev){
prev = { [current.category]: [] };
acc.push(prev);
}
prev[current.category].push({product: current.product});
return acc;
}, []);
console.log(result);

Is there any way to replace the existing object inside JSON array with new object based on key

I am having a dynamic JSON array in below format,
let main_data = [
{
"client":[
{
"name":"aaaa",
"count":"1",
"filter":{
"type":{
"name":"test3"
}
}
},
{
"name":"bbbb",
"count":"9",
"filter":{
"type":{
"name":"test2"
}
}
}
]
},
{
"compute":[
{
"name":"cccc",
"count":"6",
"filter":{
"type":{
"name":"test"
}
}
}
]
}
]
Here key "name" is unique. When updating a form, I will get an json array like below,
let new_data = [
{
"client":[
{
"name":"bbbb",
"count":"1234",
"type":{
"name":"updated_name"
}
}
}
]
}
]
I need to check the "name" in the json array in "main_data" and remove the existing one and update with the new "updated_data" into the "main_data". (no Jquery please)
Expected output,
let main_data = [
{
"client":[
{
"name":"aaaa",
"count":"1",
"filter":{
"type":{
"name":"test3"
}
}
},
{
"name":"bbbb",
"count":"123",
"filter":{
"type":{
"name":"updated_name"
}
}
}
]
},
{
"compute":[
{
"name":"cccc",
"count":"6",
"filter":{
"type":{
"name":"test"
}
}
}
]
}
]
Is there any way to achive this. Any help would be much appreciated. Thanks in advance.
Try this
let main_data = [{
client: [{
name: "aaaa",
count: "1",
filter: {
type: {
name: "test3"
}
}
},
{
name: "bbbb",
count: "9",
filter: {
type: {
name: "test2"
}
}
}
]
},
{
compute: [{
name: "cccc",
count: "6",
filter: {
type: {
name: "test"
}
}
}]
}
];
let new_data = [{
client: [{
name: "bbbb",
count: "1234",
filter: {
type: {
name: "updated_name"
}
}
}]
}];
const res = main_data.map((item, index) => {
if (item.client) {
const clients = item.client.map(client => {
if (client.name === new_data[0].client[0].name) {
client = new_data[0].client[0];
}
return client;
});
return {
client: clients
};
}
return item;
});
console.log(res);
There may very well be a fancy way to get this done but one can always just find the matching item and replace it. eg.
let main_data = [
{
"client": [
{
"name": "aaaa",
"count": "1",
"filter": {
"type": {
"name": "test3"
}
}
},
{
"name": "bbbb",
"count": "123",
"filter": {
"type": {
"name": "updated_name"
}
}
}
]
},
{
"compute": [
{
"name": "cccc",
"count": "6",
"filter": {
"type": {
"name": "test"
}
}
}
]
}
];
let new_data = [
{
"client": [
{
"name": "bbbb",
"count": "1234",
"type": {
"name": "updated_name"
}
}
]
}
];
console.log("before:" + JSON.stringify(main_data));
newItem = new_data[0]["client"][0];
mainDataList = main_data[0]["client"];
for (i = 0; i < mainDataList.length; i++) {
if (mainDataList[i].name == newItem.name) {
mainDataList[i] = newItem;
}
}
console.log("after:" + JSON.stringify(main_data));
will output
before:[{"client":[{"name":"aaaa","count":"1","filter":{"type":{"name":"test3"}}},{"name":"bbbb","count":"123","filter":{"type":{"name":"updated_name"}}}]},{"compute":[{"name":"cccc","count":"6","filter":{"type":{"name":"test"}}}]}]
after:[{"client":[{"name":"aaaa","count":"1","filter":{"type":{"name":"test3"}}},{"name":"bbbb","count":"1234","type":{"name":"updated_name"}}]},{"compute":[{"name":"cccc","count":"6","filter":{"type":{"name":"test"}}}]}]
Here's a simple way to do this, let's say your new data is at variable newData:
main_data.client.filter(item => item.name === newData.name).push(newData)

How to find the value nested inside an array of objects

Here I have to get value of file_info, I tried doing it using array.includes and array.find(), but got undefined.
My confusion here is related to, under 'facts', the first value is "==", then it has array of values associated to it. I could not figure out to find the values inside that nested object.
I even tried array.find(facts).contains(fileinfo) that did not work as well.
How can I solve this ??
"data": [
{
"task-id": "126e7267",
"type": "A",
"output": {...}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
},
....
]
}
},
{
"task-id": "5f557eac",
"type": "C",
....
},
],
I have tried to validate your json string. It seems to be invalid. For answering this question , i would assume below string to be your json :
{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}
I had tried to figure out a repetative pattern in your json but since "#value" tag is seen inside only one "facts" object below code should help you getting started . For given json , below code prints the value of "file_info"(Here , i'am assuming that "file_info" should be followed by a colon(:) i.e. "a0s5b2e6e739" is the value you are looking for) :
var jsonStr = '{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}';
var jsonObj = JSON.parse(jsonStr);
//If there is a repetative pattern , you can replace this hard coding with your pattern.
var objArray = jsonObj["data"][1]["output"]["facts"][0]["=="][1]["#value"]["facts"];
console.log(objArray);
if(objArray && objArray.length >0){
for(let i =0;i<objArray.length;i++){
if(objArray[i] && objArray[i]["=="] && objArray[i]["=="].length > 0 && objArray[i]["=="][0]["file_info"]){
//here "file_info" is fetched
console.log('here ',objArray[i]["=="][0]["file_info"]);
}
}
}
Hope above code helps you to get started.
You can map and filter the object/array to get the result if the format is fixed. Here, I am writing to a Map and retrieving the property I need at the very end.
let data = [
{
"task-id": "126e7267",
"type": "A",
"output": {}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
}
]
}
},
{
"task-id": "5f557eac",
"type": "C",
"output": {}
}
]
const map = new Map()
const facts = data
.map(d => d.output)
.filter(o => o.hasOwnProperty('facts'))
.map(d => d.facts)
.map(i => i[0]["=="][1])
.map(d => d["#value"].facts)
const item = facts.forEach(o => o.forEach(i => map.set(i["=="][0], i["=="][1])))
console.log(map.get("file_info"))

how to return an array inside an array javascript

i have an array inside an array...how do i return all the values using a for loop in javascript/angular?
for example my json...
[
{
"Name": "element1",
"Attributes": [
{"file":"document.doc"},
{"file":"document2.doc"}
]
},
{
"Name": "element2",
"Attributes": [
{"file":"document3.doc"},
{"file":"document4.doc"}
]
},
{
"Name": "element3",
"Attributes": [
{"file":"document5.doc"},
{"file":"document6.doc"}
]
}
]
having a tough time just returning all the files within attributes...only seem to be getting the first one everytime.
EDIT:
what i have so far..
function getAllFiles() {
for (var i = 0; i < Attributes.file.length; i++) {
return Attributes.file[i];
}
}
One of the methods how to get the desired output, using Array#reduce.
var json = [{Name:"element1",Attributes:[{file:"document.doc"},{file:"document2.doc"}]},{Name:"element2",Attributes:[{file:"document3.doc"},{file:"document4.doc"}]},{Name:"element3",Attributes:[{file:"document5.doc"},{file:"document6.doc"}]}],
res = json.reduce(function(s,a){
s.push(...a.Attributes.map(c => c.file));
return s;
}, []);
console.log(res);
ES5
var json = [{Name:"element1",Attributes:[{file:"document.doc"},{file:"document2.doc"}]},{Name:"element2",Attributes:[{file:"document3.doc"},{file:"document4.doc"}]},{Name:"element3",Attributes:[{file:"document5.doc"},{file:"document6.doc"}]}],
res = json.reduce(function(s,a){
s = s.concat(a.Attributes.map(c => c.file));
return s;
}, []);
console.log(res);
try
var files = [];
json.forEach(function(obj) {
obj.Attributes.forEach(function (f) {
files.push(f.file); })
});
this loops on the json array then on each element's attributes then adds the vilue of file
You could show all the files using Array methods like map and reduce:
var data = [{
"Name": "element1",
"Attributes": [{
"file": "document.doc"
},
{
"file": "document2.doc"
}
]
},
{
"Name": "element2",
"Attributes": [{
"file": "document3.doc"
},
{
"file": "document4.doc"
}
]
},
{
"Name": "element3",
"Attributes": [{
"file": "document5.doc"
},
{
"file": "document6.doc"
}
]
}
];
var files = data.map(function (obj) {
return obj.Attributes.map(function (i) {
return i.file;
});
}).reduce(function (x, y) {
return x.concat(y);
});
console.log(files);
Although Kind user's answer is better:
var data = [{
"Name": "element1",
"Attributes": [{
"file": "document.doc"
},
{
"file": "document2.doc"
}
]
},
{
"Name": "element2",
"Attributes": [{
"file": "document3.doc"
},
{
"file": "document4.doc"
}
]
},
{
"Name": "element3",
"Attributes": [{
"file": "document5.doc"
},
{
"file": "document6.doc"
}
]
}
];
var files = data.reduce(function(acc, val) {
return acc.concat(
val.Attributes.map(function(attribute) {
return attribute.file;
})
);
}, []);
console.log(files);
I renamed some variables so that the code makes more sense (to me).
Something like outerArray.innerArray. in your case arrayName.Attributes should work.

Reformat an object

I have the following:
{
"SOL": {
"B": [
"ABC",
"DEF"
],
"C": [
"JKL",
"MNO"
]
}
}
I'd like it to read:
{
"SOL": [
{
"id": "B",
"states": [
{
"id": "ABC"
},
{
"id": "DEF"
]
},
{
"id": "C",
"states": [
{
"id": "JKL"
},
{
"id": "MNO"
}
]
}
]
}
I've managed to give an "id" key to the 2nd level but I can't figure out how to add one to each of the states - how can I do that?
Code:
object.SOL = Object.keys(object.SOL).map(function (k) {
return { id: k, states: object.SOL[k] };
})
Here's a fiddle
You can just use another map inside to remap the states to objects:
object.SOL = Object.keys(object.SOL).map(function (k) {
return {
id: k,
states: object.SOL[k].map(function(i){
return {id: i };
})
}
});
Updated fiddle: https://jsfiddle.net/ouybL99u/2/
object.SOL = Object.keys(object.SOL).map(function (k) {
return { id: k, states: object.SOL[k].map(function(kk){ return {id:kk} }) };
})

Categories