How to push all generated objects into a single array? - javascript

Using the following code I want to push filtered[i] output into a single array instead of multiple arrays.
Any idea how do I do it?
var checkObject;
var filtered = s.Data.results.filter(function(el) {
return el.result.indexOf(option) > -1
});
for (var i = 0; i < filtered.length; i++) {
checkObject = filtered[i].path === 3;
if (checkObject) {
var object = [],
hash = Object.create(null),
notIn = [];
object.push(filtered[i]);
console.log(object);
//
object.forEach(function(a) {
a.result.forEach(function(b) {
hash[b] = true;
});
});
notIn = s.Data.choices.filter(function(a) {
return !hash[a.choice];
});
console.log(notIn);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Javascript group URLs by domain and directory

How can I group the URLs from a sorted list by domain and directory?
If two URLs have the same directory (just the first one after domain), then they should be grouped in an array;
Those URLs whose first directory is different, but have the same domain, should be grouped in an array;
For example, the URLs from this list:
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115",
"https://www.facebook.com/plugins/like.php?app_id=5",
"https://www.facebook.com/tr/a/?id=228037074239568",
"https://www.facebook.com/tr/b/?ev=ViewContent",
"http://www.marvel.com/abc?f=33",
"http://www.marvel.com/games?a=11",
"http://www.marvel.com/games?z=22",
"http://www.marvel.com/videos"]
Should be grouped as follows:
var group_url = [
["https://www.facebook.com/impression.php/f2e61d9df/?lid=115","https://www.facebook.com/plugins/like.php?app_id=5",],
["https://www.facebook.com/tr/a/?id=228037074239568","https://www.facebook.com/tr/b/?ev=ViewContent"],
["http://www.marvel.com/abc?f=33","http://www.marvel.com/videos"],
["http://www.marvel.com/games?a=11","http://www.marvel.com/games?z=22"]
]
I wrote some code but only managed to group the URLs by domain:
var group_url = [];
var count = 0;
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115",
"https://www.facebook.com/plugins/like.php?app_id=5",
"https://www.facebook.com/tr/?id=228037074239568",
"https://www.facebook.com/tr/?ev=ViewContent",
"http://www.marvel.com/abc?f=33",
"http://www.marvel.com/games?a=11",
"http://www.marvel.com/games?z=22",
"http://www.marvel.com/videos"]
for(i = 0; i < url_list.length; i++) {
if(url_list[i] != "") {
var current = url_list[i].replace(/.*?:\/\//g, "");
var check = current.substr(0, current.indexOf('/'));
group_url.push([])
for(var j = i; j < url_list.length; j++) {
var add_url = url_list[j];
if(add_url.indexOf(check) != -1) {
group_url[count].push(add_url);
url_list[j] = "";
}
else {
break;
}
}
count += 1;
}
}
console.log(JSON.stringify(group_url));
It seems like you want to group the URLs by domain+dir, but if they end up being alone in their group, to then regroup those by domain only.
For that you can use this script (ES5):
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115",
"https://www.facebook.com/plugins/like.php?app_id=5",
"https://www.facebook.com/tr/a/?id=228037074239568",
"https://www.facebook.com/tr/b/?ev=ViewContent",
"http://www.marvel.com/abc?f=33",
"http://www.marvel.com/games?a=11",
"http://www.marvel.com/games?z=22",
"http://www.marvel.com/videos"];
// Group the URLs, keyed by domain+dir
var hash = url_list.reduce(function (hash, url) {
// ignore protocol, and extract domain and first dir:
var domAndDir = url.replace(/^.*?:\/\//, '').match(/^.*?\..*?\/[^\/?#]*/)[0];
hash[domAndDir] = (hash[domAndDir] || []).concat(url);
return hash;
}, {});
// Regroup URLs by domain only, when they are alone for their domain+dir
Object.keys(hash).forEach(function (domAndDir) {
if (hash[domAndDir].length == 1) {
var domain = domAndDir.match(/.*\//)[0];
hash[domain] = (hash[domain] || []).concat(hash[domAndDir]);
delete hash[domAndDir];
}
});
// Convert hash to array
var result = Object.keys(hash).map(function(key) {
return hash[key];
});
// Output result
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
NB: I did not use ES6 as you mentioned ES5 in comments, but consider using ES6 Map for such a hash, which is better suited for the job.
urllistextended=url_list.map(function(el){return el.split("://")[1].split("/");});//remove protocol, split by /
var obj={};
for(var index in urllistextended){
var el=urllistextended[index];
obj[el[0]]=obj[el[0]]||{};
obj[el[0]][el[1]]=obj[el[0]][el[1]]||[];
obj[el[0]][el[1]].push(url_list[index]);
}
Use like this:
obj["www.facebook.com"];//{plugins:[],tr:[]}
obj["www.facebook.com"]["tr"];//[url1,url2]
http://jsbin.com/qacasexowi/edit?console enter "result"
I would recommend using the excellent URI.js library which offers great ways to parse, query and manipulate URLs: http://medialize.github.io/URI.js/
For example to work with the path (what you are referring to as directory) you could easily do the following (taken straight from the api docs):
var uri = new URI("http://example.org/foo/hello.html");
// get pathname
uri.pathname(); // returns string "/foo/hello.html"
// set pathname
uri.pathname("/foo/hello.html"); // returns the URI instance for chaining
// will encode for you
uri.pathname("/hello world/");
uri.pathname() === "/hello%20world/";
// will decode for you
uri.pathname(true) === "/hello world/";
// will return empty string for empty paths, but:
URI("").path() === "";
URI("/").path() === "/";
URI("http://example.org").path() === "/";
The rest should be easy going.
I suggest to use an object and group by domain and by the first string after the domain. Then iterate the tree and reduce it to the wanted structure.
This solution works with unsorted data.
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115", "https://www.facebook.com/plugins/like.php?app_id=5", "https://www.facebook.com/tr/a/?id=228037074239568", "https://www.facebook.com/tr/b/?ev=ViewContent", "http://www.marvel.com/abc?f=33", "http://www.marvel.com/games?a=11", "http://www.marvel.com/games?z=22", "http://www.marvel.com/videos"],
temp = [],
result;
url_list.forEach(function (a) {
var m = a.match(/.*?:\/\/([^\/]+)\/?([^\/?]+)?/);
m.shift();
m.reduce(function (r, b) {
if (!r[b]) {
r[b] = { _: [] };
r._.push({ name: b, children: r[b]._ });
}
return r[b];
}, this)._.push(a);
}, { _: temp });
result = temp.reduce(function (r, a) {
var top = [],
parts = [];
a.children.forEach(function (b) {
if (b.children.length === 1) {
top.push(b.children[0]);
} else {
parts.push(b.children);
}
});
return top.length ? r.concat([top], parts) : r.concat(parts);
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This does exactly what you need:
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115",
"https://www.facebook.com/plugins/like.php?app_id=5",
"https://www.facebook.com/tr/a/?id=228037074239568",
"https://www.facebook.com/tr/b/?ev=ViewContent",
"http://www.marvel.com/abc?f=33",
"http://www.marvel.com/games?a=11",
"http://www.marvel.com/games?z=22",
"http://www.marvel.com/videos"];
var folderGroups = {};
for (var i = 0; i < url_list.length; i++) {
var myRegexp = /.*\/\/[^\/]+\/[^\/\?]+/g;
var match = myRegexp.exec(url_list[i]);
var keyForUrl = match[0];
if (folderGroups[keyForUrl] == null) {
folderGroups[keyForUrl] = [];
}
folderGroups[keyForUrl].push(url_list[i]);
}
var toRemove = [];
Object.keys(folderGroups).forEach(function(key,index) {
if (folderGroups[key].length == 1) {
toRemove.push(key);
}
});
for (var i = 0; i < toRemove.length; i++) {
delete folderGroups[toRemove[i]];
}
//console.log(folderGroups);
var domainGroups = {};
for (var i = 0; i < url_list.length; i++) {
//Check if collected previously
var myRegexpPrev = /.*\/\/[^\/]+\/[^\/\?]+/g;
var matchPrev = myRegexpPrev.exec(url_list[i]);
var checkIfPrevSelected = matchPrev[0];
debugger;
if (folderGroups[checkIfPrevSelected] != null) {
continue;
}
//Get for domain group
var myRegexp = /.*\/\/[^\/]+/g;
var match = myRegexp.exec(url_list[i]);
var keyForUrl = match[0];
if (domainGroups[keyForUrl] == null) {
domainGroups[keyForUrl] = [];
}
domainGroups[keyForUrl].push(url_list[i]);
}
//console.log(domainGroups);
var finalResult = {};
$.extend(finalResult, folderGroups, domainGroups);
console.log(Object.values(finalResult));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How to filter elements in array in JavaScript object

If I have a JavaScript object like this:
{"products":
[
{
"id":"6066157707315577",
"reference_prefix":"BB",
"name":"BeanieBaby",
"product_line":false,
"has_ideas":true
},
{
"id":"6066197229601550",
"reference_prefix":"BBAGS",
"name":"BlackBags",
"product_line":false,
"has_ideas":false
}
],
"pagination": {
"total_records":4,
"total_pages":1,
"current_page":1
}
}
How do I write a function in js to loop over each pair and only return the elements of the array where has_ideas === true?
I have started with this but I'm stuck. Clearly I am new to this. Any help appreciated.
product: function(mybundle) {
var json = JSON.parse(mybundle.response.content);
for(var i = 0; i < json.length; i++) {
var obj = json[i];
if (json[i].id === "has_ideas" && json[i].value === true) {
return json;
}
return [];
}
}
You can filter out each pair by simply checking that property:
var json = {"products":[{"id":"6066157707315577","reference_prefix":"BB","name":"BeanieBaby","product_line":false,"has_ideas":true},{"id":"6066197229601550","reference_prefix":"BBAGS","name":"BlackBags","product_line":false,"has_ideas":false}],"pagination":{"total_records":4,"total_pages":1,"current_page":1}}
var stuff = json.products.filter(function(obj) {
return obj.has_ideas === true
});
console.log(stuff);
Demo:http://jsfiddle.net/bsyk18cb/
try this
product: function(mybundle) {
var json = JSON.parse(mybundle.response.content);
for(var i = 0; i < json.length; i++) {
if(json[i].has_ideas === true){
return json;
}
return [];
}
}
You want to check the "has_ideas" attribute and if true, return the id.
product: function(mybundle) {
var json = JSON.parse(mybundle.response.content);
for(var i = 0; i < json.length; i++) {
if (json[i].has_ideas === true) {
return json[i].id;
}
return [];
}
}
Use code below.
this will return array of elements having has_ideas=true
var json = "{'products':"+
"["+
"{"+
"'id':'6066157707315577',"+
"'reference_prefix':'BB',"+
"'name':'BeanieBaby',"+
"'product_line':false,"+
"'has_ideas':true"+
"},"+
"{"+
"'id':'6066197229601550',"+
"'reference_prefix':'BBAGS',"+
"'name':'BlackBags',"+
"'product_line':false,"+
"'has_ideas':false"+
"}"+
"],"+
"'pagination': {"+
"'total_records':4,"+
"'total_pages':1,"+
"'current_page':1"+
"}"+
"}";
function filter(){
var jsonArr = [];
var gList = eval( "(" + json + ")");
alert(gList.products.length);
for(var i=0;i<gList.products.length;i++){
if(gList.products[i].has_ideas){
jsonArr.push(gList.products[i]);
}
}
return jsonArr;
}
Demo

Remove object from array object Jquery

I am creating array object like follows:
var numberOfSameDeficiency = [];
for (var i = 0; i < result.length; i++) {
var deficiencyId = result[i].Deficiency_Id;
var deficiencyName = result[i].DeficiencyName;
//check to see if this deficiency is already in the list of available selections
if ($("#drpDeficiency option[value='" + deficiencyId + "']").length == 0) {
var option = $('<option>');
option.attr('value', deficiencyId);
option.text(deficiencyName);
$select.append(option);
}
else {
Tests = {};
Tests.TestId = testId;
Tests.DeficiencyId = deficiencyId;
numberOfSameDeficiency.push(Tests);
}
}
And I want to remove object on different function like this:
for (var i = 0; i < result.length; i++) {
console.log(numberOfSameDeficiency);
var isFound = false;
var deficiencyId = result[i].Deficiency_Id;
if (numberOfSameDeficiency) {
numberOfSameDeficiency.forEach(function (entry) {
if (entry.DeficiencyId != deficiencyId) {
isFound = true;
**numberOfSameDeficiency.splice(entry, 1); // Generating Error (Remove all items from array object)**
return;
}
});
// console.log("end if");
}
if (!isFound) {
$("#drpDeficiency option[value='" + deficiencyId + "']").remove();
}
}
So what line code should be there to remove particular object from array object.
Try this
for( i=myArray.length-1; i>=0; i--) {
if( myArray[i].field == "money") myArray.splice(i,1);
}
This also works
myArray = [{name:"Alpesh", lines:"2,5,10"},
{name:"Krunal", lines:"1,19,26,96"},
{name:"Deep",lines:"3,9,62,36" }]
johnRemovedArray = myArray
.filter(function (el) {
return el.name !== "Krunal";
});
Create this prototype function:
Array.prototype.removeElement = function (el) {
for(let i in this){
if(this.hasOwnProperty(i))
if(this[i] === el)
this.splice(i, 1);
}
}
Then call:
let myArray = ['a','b','c','d'];
myArray.removeElement("c");
It also works with objects:
let myObj1 = {name: "Mike"},
myObj2 = {name: "Jenny"},
myArray = [myObj1, myObj2];
myArray.removeElement(myObj2);

Filtering an array of Objects in javascript

I'm really new to JS, and I'm now stuck on a task, hope someone can guide me through it.
I have an Array of Objects, like this one:
var labels = [
// labels for pag 1
{pageID:1, labels: [
{labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
{labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
{labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
]},
// labels for pag 2
{pageID:2, labels: [
{labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
{labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
{labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
]}
]
What I am trying to do is write a function to return me an array of labels (Objects) for a specific page and a specific lang. By calling this function specifying pageID 1 and lang eng, I'm basically trying to build an array like this one:
var desideredArray = [
{labelID:0, text:'Txt1 Eng'},
{labelID:1, text:'Txt1 Eng'},
{labelID:2, text:'Txt2 Eng'}
]
Now, I'm trying to write the function to retrieve/build the new array:
this.getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function( obj ) {
return obj.pageID == numPage;
});
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
// simpleLabelObject.text = ?????
results[i] = simpleLabelObject;
}
console.log (results);
};
...but how can I access the right value (the one corresponding the lang selected) in the content property?
You can use the same technique as the one used to keep the matching page: the filter method.
this.getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function( obj ) {
return obj.pageID == numPage;
});
var contentFilter = function(obj){ return obj.lang === lang};
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var matching = tempResult[i].content.filter(contentFilter);
simpleLabelObject.text = matching[0].text;
desiredResults[i] = simpleLabelObject;
}
console.log (desiredResults);
};
I didn't do bound checks because in your code you assumed there is always a matching element, but it would probably be wise to do it.
And if you want to avoid creating two closures each time the function is called, you can prototype an object for that:
var Filter = function(numPage, lang) {
this.numPage = numPage;
this.lang = lang;
};
Filter.prototype.filterPage = function(obj) {
return obj.pageID === this.numPage;
}
Filter.prototype.filterLang = function(obj) {
return obj.lang === this.lang;
}
Filter.prototype.filterLabels = function(labels) {
var result = labels.filter(this.filterPage, this);
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var matching = tempResult[i].content.filter(this.filterLang, this);
simpleLabelObject.text = matching[0].text;
desiredResults[i] = simpleLabelObject;
}
return desiredResults;
}
console.log(new Filter(1, "eng").filterLabels(labels));
Just filter again:
var getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function (obj) {
return obj.pageID == numPage;
});
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i = 0; i < tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var lg = tempResult[i].content.filter(function (lg) {
return lg.lang == lang;
});
simpleLabelObject.text = lg[0].text;
desiredResults.push(simpleLabelObject);
}
console.log(desiredResults);
};
http://jsfiddle.net/9q5zF/
A rather 'safe' implementation for cases when pages have the same pageID and multiple contents with the same lang:
this.getLabelsForPageAndLang = function(numPage, lang) {
var result = [];
var pages = labels.filter(function( obj ) {
return obj.pageID === numPage;
});
for (var p = pages.length - 1; p >= 0; p--) {
var page = pages[p];
for(var i = page.labels.length - 1; i >= 0; i--) {
var labelId = page.labels[i].labelID;
for (var j = page.labels[i].content.length - 1; j >= 0; j--){
if (page.labels[i].content[j].lang === lang) {
result.push({labelID: labelId, test: page.labels[i].content[j].text});
}
}
}
}
console.log(result);
}
Fiddle: http://jsfiddle.net/6VQUm/

filter objects matching details

Functions works fine, they filter inventory by barcode, and manufacturer. I want to make it like default angularjs filtering. If I choose manufacturer - LG and barcode - 112 and if they don't match, then it shouldn't display anything.
But for now it displays separately, when i click on filter function it filters barcode when on filter2 function filter manufacturer
$scope.filter = function(barcode) {
var filtered = [];
for(var i = 0; i < $scope.inventories.length; i++){
if($scope.inventories[i].barcode == barcode){
filtered.push($scope.inventories[i]);
}
}
$scope.filtered_inventories = filtered;
};
$scope.filter2 = function(manufacturer) {
var filtered = [];
for(var i = 0; i < $scope.inventories.length; i++){
if($scope.inventories[i].manufacturer == manufacturer){
filtered.push($scope.inventories[i]);
}
}
$scope.filtered_inventories = filtered;
};
Try this
$scope.filter = function (barcode, manufacturer) {
var filtered = [];
for(var i = 0; i < $scope.inventories.length; i++){
if($scope.inventories[i].barcode == barcode || $scope.inventories[i].manufacturer == manufacturer){
filtered.push($scope.inventories[i]);
}
}
$scope.filtered_inventories = filtered;
};
You could create a more general way of filtering:
$scope.filterByBarcode = function(list, key, value) {
return list.filter(function(item){
return item[key] === value;
});
};
And when you filter you could call:
$scope.filtered_inventories = $scope.filter($scope.filter($scope.inventories, 'barcode', 112), 'manufacturer', 'LG')
But to simplify that you could create a function:
$scope.filterByBarcodeAndManufacturer = function(barcode, manufacturer) {
$scope.filtered_inventories =
$scope.filter($scope.filter($scope.inventories, 'barcode', barcode), 'manufacturer', manufacturer);
}

Categories

Resources