What is the most concise and efficient way to find out if a JavaScript array contains duplicates and merge them into new array please ?
I tried Lodash / d3 / underscoreJs but none of them generate clean result so I tried this code ->
var arr = [
{
"title": "My unique title",
"link": "domainlinkto-my-unique-title",
"image": "someurlto/my-unique-title-image",
"date": "Mon, 29 Jul 2019 02:25:08 -0000",
"site": "site1"
},
{
"title": "A duplicate title",
"link": "somedomainlinkto-a-duplicate-title/",
"image": "randomurlto/a-duplicate-title.jpg",
"date": "Sun, 25 Aug 2019 15:52:59 -0000",
"site": "site1"
},
{
"title": "A duplicate title",
"link": "otherdomainlinkto-a-duplicate-title/",
"image": "anotherurlto/duplicate-title.jpg",
"date": "Sun, 25 Aug 2019 21:09:37 -0000",
"site": "site2"
},
{
"title": "A DUPLICATE TITLE",
"link": "someotherdomainlinkto-a-duplicate-title/",
"image": "someurlto/aduplicatetitle.jpg",
"date": "Sat, 24 Aug 2019 18:43:38 -0000",
"site": "site3"
},
{
"title": "Other duplicate: title",
"link": "anydomainlinkto-other-duplicate-title/",
"image": "anotherdomainurlto/other-duplicate-title.jpg",
"date": "Mon, 26 Aug 2019 00:37:28 -0000",
"site": "site2"
},
{
"title": "Other duplicate : title",
"link": "anyotherdomainlinkto-other-duplicate-title/",
"image": "exampleurlto/hjKGHK45huu.jpg",
"date": "Mon, 26 Aug 2019 00:37:28 -0000",
"site": "site5"
},
{
"title": "Other unique title",
"link": "anydomainlinkto-other-unique-title/",
"image": "anyotherurlto/img/other-title.jpg",
"date": "Mon, 26 Aug 2019 09:18:10 -0000",
"site": "site3"
}
];
Array.prototype.groupBy = function (props) {
var arr = this;
var partialResult = {};
var imgResult = {};
arr.forEach(el=>{
var grpObj = {};
var grpImg = {};
props.forEach(prop=>{
grpObj.title = el.title;
grpImg.image = el.image;
});
var key = JSON.stringify(grpObj);
var keyImg = JSON.stringify(grpImg);
if(!imgResult[key]) {
imgResult[key] = grpImg.image;
} else {
imgResult[key] = el.image;
}
if(!partialResult[key]) partialResult[key] = [];
partialResult[key].push(
{
link: el.link,
site: el.site,
date: el.date
});
});
var finalResult = Object.keys(partialResult, imgResult).map(key=>{
var keyObj = JSON.parse(key);
keyObj.links = partialResult[key];
keyObj.image = imgResult[key];
return keyObj;
})
return finalResult;}
var filtered = arr.groupBy(['title']);
console.log(filtered);
BUT...
As you can see [titles] in UPPERCASE and "Other duplicate : title" is not taken as duplicate
WHAT I WOULD DO --->
var expected = [
{
"title": "My unique title",
"links": [{"date": "Mon, 29 Jul 2019 02:25:08 -0000","site": "site1", "link": "domainlinkto-my-unique-title"}],
"image": "someurlto/my-unique-title-image",
},
{
"title": "My duplicate title",
"links": [
{"date": "Sun, 25 Aug 2019 15:52:59 -0000","site": "site1","link":"somedomainlinkto-a-duplicate-title/"},
{"date": "Sun, 25 Aug 2019 21:09:37 -0000","site": "site2","link": "otherdomainlinkto-a-duplicate-title/"},
{"date": "Sat, 24 Aug 2019 18:43:38 -0000","site": "site3","link": "someotherdomainlinkto-a-duplicate-title/"}
],
"image": "randomurlto/a-duplicate-title.jpg",
},
{
"title": "Other duplicate: title",
"links": [
{"date": "Sun, 25 Aug 2019 15:52:59 -0000","site": "site2","link":"anydomainlinkto-other-duplicate-title/"},
{"date": "Mon, 26 Aug 2019 00:37:28 -0000","site": "site5","link": "anyotherdomainlinkto-other-duplicate-title/"}
],
"image": "anotherdomainurlto/other-duplicate-title.jpg",
},
{
"title": "Other unique title",
"links": [{"date": "Mon, 26 Aug 2019 09:18:10 -0000","site": "site1", "link": "anydomainlinkto-other-unique-title/"}],
"image": "anyotherurlto/img/other-title.jpg",
"site": "site3"
}
];
console.log(expected);
Hi Genious
What is the most concise and efficient way to find out if a JavaScript array contains duplicates and merge them into new array please ?
I tried Lodash / d3 / underscoreJs but none of them generate clean result so I tried this code ->
var arr = [
{
"title": "My unique title",
"link": "domainlinkto-my-unique-title",
"image": "someurlto/my-unique-title-image",
"date": "Mon, 29 Jul 2019 02:25:08 -0000",
"site": "site1"
},
{
"title": "A duplicate title",
"link": "somedomainlinkto-a-duplicate-title/",
"image": "randomurlto/a-duplicate-title.jpg",
"date": "Sun, 25 Aug 2019 15:52:59 -0000",
"site": "site1"
},
{
"title": "A duplicate title",
"link": "otherdomainlinkto-a-duplicate-title/",
"image": "anotherurlto/duplicate-title.jpg",
"date": "Sun, 25 Aug 2019 21:09:37 -0000",
"site": "site2"
},
{
"title": "A DUPLICATE TITLE",
"link": "someotherdomainlinkto-a-duplicate-title/",
"image": "someurlto/aduplicatetitle.jpg",
"date": "Sat, 24 Aug 2019 18:43:38 -0000",
"site": "site3"
},
{
"title": "Other duplicate: title",
"link": "anydomainlinkto-other-duplicate-title/",
"image": "anotherdomainurlto/other-duplicate-title.jpg",
"date": "Mon, 26 Aug 2019 00:37:28 -0000",
"site": "site2"
},
{
"title": "Other duplicate : title",
"link": "anyotherdomainlinkto-other-duplicate-title/",
"image": "exampleurlto/hjKGHK45huu.jpg",
"date": "Mon, 26 Aug 2019 00:37:28 -0000",
"site": "site5"
},
{
"title": "Other unique title",
"link": "anydomainlinkto-other-unique-title/",
"image": "anyotherurlto/img/other-title.jpg",
"date": "Mon, 26 Aug 2019 09:18:10 -0000",
"site": "site3"
}
];
Array.prototype.groupBy = function (props) {
var arr = this;
var partialResult = {};
var imgResult = {};
arr.forEach(el=>{
var grpObj = {};
var grpImg = {};
props.forEach(prop=>{
grpObj.title = el.title;
grpImg.image = el.image;
});
var key = JSON.stringify(grpObj);
var keyImg = JSON.stringify(grpImg);
if(!imgResult[key]) {
imgResult[key] = grpImg.image;
} else {
imgResult[key] = el.image;
}
if(!partialResult[key]) partialResult[key] = [];
partialResult[key].push(
{
link: el.link,
site: el.site,
date: el.date
});
});
var finalResult = Object.keys(partialResult, imgResult).map(key=>{
var keyObj = JSON.parse(key);
keyObj.links = partialResult[key];
keyObj.image = imgResult[key];
return keyObj;
})
return finalResult;}
var filtered = arr.groupBy(['title']);
console.log(filtered);
BUT...
As you can see [titles] in UPPERCASE and "Other duplicate : title" is not taken as duplicate
WHAT I WOULD DO --->
[
{
"title": "My unique title",
"links": [{"date": "Mon, 29 Jul 2019 02:25:08 -0000","site": "site1", "link": "domainlinkto-my-unique-title"}],
"image": "someurlto/my-unique-title-image",
},
{
"title": "My duplicate title",
"links": [
{"date": "Sun, 25 Aug 2019 15:52:59 -0000","site": "site1","link":"somedomainlinkto-a-duplicate-title/"},
{"date": "Sun, 25 Aug 2019 21:09:37 -0000","site": "site2","link": "otherdomainlinkto-a-duplicate-title/"},
{"date": "Sat, 24 Aug 2019 18:43:38 -0000","site": "site3","link": "someotherdomainlinkto-a-duplicate-title/"}
],
"image": "randomurlto/a-duplicate-title.jpg",
},
{
"title": "Other duplicate: title",
"links": [
{"date": "Sun, 25 Aug 2019 15:52:59 -0000","site": "site2","link":"anydomainlinkto-other-duplicate-title/"},
{"date": "Mon, 26 Aug 2019 00:37:28 -0000","site": "site5","link": "anyotherdomainlinkto-other-duplicate-title/"}
],
"image": "anotherdomainurlto/other-duplicate-title.jpg",
},
{
"title": "Other unique title",
"links": [{"date": "Mon, 26 Aug 2019 09:18:10 -0000","site": "site1", "link": "anydomainlinkto-other-unique-title/"}],
"image": "anyotherurlto/img/other-title.jpg",
"site": "site3"
}
];
I'm sure this is not the better way to do that (we are agree) so I'm asking stackoverflow genious...
Thanks for reading and time spent for thinking about my problem
I'd just lowercase the title before building up the json object for grouping. And I'd use object destructuring to clean up things, as well as just one hashtable, and I don't see the sense in a generic Array.prototype.groupBy if you hardcode properties in it:
const hash = {}, result = [];
for(const { title, link, image, date, site } of input) {
const key = JSON.stringify({ title: title.toLowerCase().replace(/ /g, ""), });
if(hash[key]) {
hash[key].push({ link, date, site });
} else {
result.push({ title, image, links: hash[key] = [{ link, date, site }], });
}
}
Seems like you want to group by lowercase titles without spaces :
var arr = [{"title":"My unique title","link":"domainlinkto-my-unique-title","image":"someurlto/my-unique-title-image","date":"Mon, 29 Jul 2019 02:25:08 -0000","site":"site1"},{"title":"A duplicate title","link":"somedomainlinkto-a-duplicate-title/","image":"randomurlto/a-duplicate-title.jpg","date":"Sun, 25 Aug 2019 15:52:59 -0000","site":"site1"},{"title":"A duplicate title","link":"otherdomainlinkto-a-duplicate-title/","image":"anotherurlto/duplicate-title.jpg","date":"Sun, 25 Aug 2019 21:09:37 -0000","site":"site2"},{"title":"A DUPLICATE TITLE","link":"someotherdomainlinkto-a-duplicate-title/","image":"someurlto/aduplicatetitle.jpg","date":"Sat, 24 Aug 2019 18:43:38 -0000","site":"site3"},{"title":"Other duplicate: title","link":"anydomainlinkto-other-duplicate-title/","image":"anotherdomainurlto/other-duplicate-title.jpg","date":"Mon, 26 Aug 2019 00:37:28 -0000","site":"site2"},{"title":"Other duplicate : title","link":"anyotherdomainlinkto-other-duplicate-title/","image":"exampleurlto/hjKGHK45huu.jpg","date":"Mon, 26 Aug 2019 00:37:28 -0000","site":"site5"},{"title":"Other unique title","link":"anydomainlinkto-other-unique-title/","image":"anyotherurlto/img/other-title.jpg","date":"Mon, 26 Aug 2019 09:18:10 -0000","site":"site3"}]
var result = arr.reduce((o, { title, image, link, date, site }, k) => (
( o[k = title.toLowerCase().replace(/ /g, '')] = o[k] || { title, image, links: [] } )
.links.push({ date, site, link }), o), {})
console.log( Object.values(result) )
If it has to work in IE too :
var arr = [{"title":"My unique title","link":"domainlinkto-my-unique-title","image":"someurlto/my-unique-title-image","date":"Mon, 29 Jul 2019 02:25:08 -0000","site":"site1"},{"title":"A duplicate title","link":"somedomainlinkto-a-duplicate-title/","image":"randomurlto/a-duplicate-title.jpg","date":"Sun, 25 Aug 2019 15:52:59 -0000","site":"site1"},{"title":"A duplicate title","link":"otherdomainlinkto-a-duplicate-title/","image":"anotherurlto/duplicate-title.jpg","date":"Sun, 25 Aug 2019 21:09:37 -0000","site":"site2"},{"title":"A DUPLICATE TITLE","link":"someotherdomainlinkto-a-duplicate-title/","image":"someurlto/aduplicatetitle.jpg","date":"Sat, 24 Aug 2019 18:43:38 -0000","site":"site3"},{"title":"Other duplicate: title","link":"anydomainlinkto-other-duplicate-title/","image":"anotherdomainurlto/other-duplicate-title.jpg","date":"Mon, 26 Aug 2019 00:37:28 -0000","site":"site2"},{"title":"Other duplicate : title","link":"anyotherdomainlinkto-other-duplicate-title/","image":"exampleurlto/hjKGHK45huu.jpg","date":"Mon, 26 Aug 2019 00:37:28 -0000","site":"site5"},{"title":"Other unique title","link":"anydomainlinkto-other-unique-title/","image":"anyotherurlto/img/other-title.jpg","date":"Mon, 26 Aug 2019 09:18:10 -0000","site":"site3"}];
var result = arr.reduce(function(o, v) {
var key = v.title.replace(/ /g, '').toLowerCase();
if (!o[key]) o[key] = { title: v.title, image: v.image, links: [] };
o[key].links.push({ date: v.date, site: v.site, link: v.link });
return o;
}, {});
console.log( Object.keys(result).map(function(k) { return result[k]; }) );
I want to create a line graph like below fiddle,
http://jsfiddle.net/wRDXt/2/
Here the date is used as new Date(2013, 17, 1).
I have json contents as follows,
[{
"_id": "bb68d8a2-8778-4c85-8616-ed1e96a61ea6",
"FLAG": "public",
"STATUS": "active",
"DESCRIPTION": "df",
"DATE_TIME": "04-10-2016 16:39:39",
"TOKEN": "bge2jb",
"LAST_UPDATED": "Tue Oct 04 16:39:39 IST 2016"
},
{
"_id": "556ae8ad-7291-4303-a9e4-618a82694600",
"FLAG": "public",
"STATUS": "active",
"DESCRIPTION": "d",
"DATE_TIME": "04-10-2016 16:52:20",
"TOKEN": "16l4jal",
"LAST_UPDATED": "Tue Oct 04 16:52:20 IST 2016"
},
{
"_id": "98db36ba-392d-4df2-ac6c-820eaf582a11",
"FLAG": "public",
"STATUS": "active",
"DESCRIPTION": "uyk",
"DATE_TIME": "07-10-2016 12:13:10",
"TOKEN": "dfl5ja",
"LAST_UPDATED": "Fri Oct 07 12:13:10 IST 2016"
}]
My date format, which came from api call is like 07-10-2016 12:13:10 or Fri Oct 07 12:13:10 IST 2016.
If I pass this date, I am getting following error in console,
Uncaught TypeError: minDate.getDate is not a function
How do I pass my date to this and get the graph.
My fiddle is http://jsfiddle.net/wRDXt/190/
The date in your dataset is not a date-object, but a string. Therefore it does not have a getDate()-function and you get the error you get.
To fix this, right after you have declared your dataset, loop through all entries in the dataset and redefine date by parsing the date-string:
dataset.forEach(function(d) {
d.date = d3.time.format("%d-%m-%Y %H:%M:%S").parse(d.date);
});
See fiddle: http://jsfiddle.net/wRDXt/204/
Reference for d3.time.format
I need to get rid of double quotes in my JSON string, this is how I am forming an array and then converting it to JSON
$dinnerDetails = array();
foreach ($dinners as $dinner) {
$dinnerDetails[] = array(
"title" => $dinner->getName(),
"data" => $dinner->getDate()
);
}
$dinnerDetails = json_encode($dinnerDetails);
Inside my view when i dump $dinnerDetails I see the following
string '[
{
"title": "Formal Dinner",
"data": "Tue Apr 05 2016 05:00:00 GMT+0500 (PKT)"
},
{
"title": "Formal Dinner",
"data": "Tue Apr 05 2016 05:00:00 GMT+0500 (PKT)"
},
{
"title": "Black Tie",
"data": "Wed Apr 13 2016 05:00:00 GMT+0500 (PKT)"
},
{
"title": "Formal Dinner",
"data": "Fri Apr 08 2016 05:00:00 GMT+0500 (PKT)"
}
]
and when I assign this to a JS variable this is how see it in the source
var dinners = [
{
"title": "Formal Dinner",
"data": "Tue Apr 05 2016 05:00:00 GMT+0500 (PKT)"
},
{
"title": "Formal Dinner",
"data": "Tue Apr 05 2016 05:00:00 GMT+0500 (PKT)"
},
{
"title": "Black Tie",
"data": "Wed Apr 13 2016 05:00:00 GMT+0500 (PKT)"
},
{
"title": "Formal Dinner",
"data": "Fri Apr 08 2016 05:00:00 GMT+0500 (PKT)"
},
{
"title": "Formal Dinner",
"data": "Sat Apr 16 2016 05:00:00 GMT+0500 (PKT)"
},
{
"title": "Formal Dinner",
"data": "Mon Mar 28 2016 05:00:00 GMT+0500 (PKT)"
}
];
I am using Symfony framework and this is how I am passing $dinnerDetails to view
return $this->render('AppBundle:admin/college:edit.html.twig', array(
'dinners' => $dinnerDetails
));
and then inside twig I am assigning to js variable like this
var dinner = jQuery.parseJSON(dinners);
In JS i even tried doing JSON.parse(dinners.replace(""",'"')); but this does not help.
The output that I am looking for is something like this
[
{
title: "All Day Event",
date: "Fri Apr 08 2016 05:00:00 GMT+0500",
},
{
title: "Long Event",
date: "Fri Apr 08 2016 05:00:00 GMT+0500",
},
]
I will really appreciate a help here.
try the raw-filter in your template. Something like this:
{{ dinners|raw }}
2nd. you have serialized a PHP-Object into a JSON-string.
If you paste this string inside a script-block this string will be interpreted as JS.
It is JS-code now, not a string anymore. You don't have to parse it; actually you cannot parse it.
<script> var dinner = {{ dinners|raw }}; </script>
Inside your controller or php file use below code.
<?php
$arrDinnerDetails = array();
foreach ($dinners as $dinner)
{
$arrDinnerDetails[] = array(
"title" => $dinner->getName(),
"data" => $dinner->getDate()
);
}
return $this->render('AppBundle:admin/college:edit.html.twig', array(
'arrDinnerDetails' => $arrDinnerDetails
));
?>
Inside your view file, use below code.
<script>
var strJsonDinner = JSON.stringify('<?php echo json_encode($arrDinnerDetails); ?>');
</script>
I have a json object as follows.
[{
"id": "1",
"username": "vishnu",
"FromDate": "Thu Apr 21 2016 10:56:45 GMT+0530 (India Standard Time)",
"selectedProject": "createwhimsy",
"task": "fixing bugs",
"time": "1"
}, {
"id": "2",
"username": "vishnu",
"FromDate": "Wed Mar 02 2016 10:56:45 GMT+0530 (India Standard Time)",
"selectedProject": "createwhimsy",
"task": "working on ui of creatwhimsy home page",
"time": "2"
}, {
"id": "3",
"username": "vishnu",
"FromDate": "Wed Mar 02 2016 10:56:45 GMT+0530 (India Standard Time)",
"selectedProject": "bigiron",
"task": "working on api",
"time": "5"
}, {
"id": "4",
"username": "vishnu",
"FromDate": "Sat Jul 30 2016 12:03:20 GMT+0530 (India Standard Time",
"selectedProject": "timetracker",
"task": "working on ui of creatwhimsy home page and admin side home page",
"time": "1"
}, {
"id": "5",
"username": "vishnu",
"FromDate": "Wed Jan 02 2016 10:56:45 GMT+0530 (India Standard Time)",
"selectedProject": "createwhimsy",
"task": "fixing bugs",
"time": "1"
}]
Let the object name be Data. I want to make a new object fro Data, but it should only contain "selectedProject" and "time".
How to do that in angularjs?
You can iterate and create a new object with desire data. For this you can use javascript push() function.
what you need to do is
$scope.log = [];
angular.forEach($scope.names, function(value, key){
$scope.log.push({"selectedProject":value.selectedProject,"time":value.time});
});
Here is JS fiddle: http://jsfiddle.net/kyaqzgo6/4/
A sample code for you:
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = [{
"id": "1",
"username": "vishnu",
"FromDate": "Thu Apr 21 2016 10:56:45 GMT+0530 (India Standard Time)",
"selectedProject": "createwhimsy",
"task": "fixing bugs",
"time": "1"
}, {
"id": "2",
"username": "vishnu",
"FromDate": "Wed Mar 02 2016 10:56:45 GMT+0530 (India Standard Time)",
"selectedProject": "createwhimsy",
"task": "working on ui of creatwhimsy home page",
"time": "2"
}, {
"id": "3",
"username": "vishnu",
"FromDate": "Wed Mar 02 2016 10:56:45 GMT+0530 (India Standard Time)",
"selectedProject": "bigiron",
"task": "working on api",
"time": "5"
}, {
"id": "4",
"username": "vishnu",
"FromDate": "Sat Jul 30 2016 12:03:20 GMT+0530 (India Standard Time",
"selectedProject": "timetracker",
"task": "working on ui of creatwhimsy home page and admin side home page",
"time": "1"
}, {
"id": "5",
"username": "vishnu",
"FromDate": "Wed Jan 02 2016 10:56:45 GMT+0530 (India Standard Time)",
"selectedProject": "createwhimsy",
"task": "fixing bugs",
"time": "1"
}];
$scope.log = [];
angular.forEach($scope.names, function(value, key){
$scope.log.push({"selectedProject":value.selectedProject,"time":value.time});
});
console.log($scope.log);
});
</script>
Try something like this:
function SomeFunction() {
function getdata(callback, url) {
var obj= {};
$http.get(url).success(function(response) {
if (response.jsonname[0].length > 0) {
for (var i = 0; i < response.jsonname[0].length; i++) {
obj= {
selectedProject:response.jsonname[0][i].selectedProject,
time:response.jsonname[0][i].time
}
}
} else {
}
}).error(function() {
//something
}).then(function() {
callback(obj);
});;
}
return {
getdata: getdata
}
}