Selecting multiple properties in Javascript or D3 - javascript

I'm trying to remove a few data points from a map created in D3.
Here I'm removing a property with name matching "Luxembourg", but I would also like to remove a property with name matching "Liechtenstein". How should I write this?
.filter(function(labels) {
return labels.properties.name != "Luxembourg";
})
I have tried using javascript references but I'm having trouble applying these.

How about using Array.prototype.indexOf
.filter(function(labels) {
var toFilter = ['Luxembourg', 'Liechtenstein']
return toFilter.indexOf(labels.properties.name) !== -1
})

Something simple like this will do:
var countriesToRemove = [ "Luxembourg", "Liechtenstein"]
data.filter(function(labels) {
return countriesToRemove.indexOf(labels.properties.name) >= 0
})

Related

Can I use .includes() to determines whether an array includes a certain element based on an array of strings instead of a single string?

Right now if I use this snippet of code, I get all elements whose region property is "Demacia"
let filtered = this.cards.filter((card) => {
return card.region.includes("Demacia");
})
Now I want to be able to get all elements whose property region is either "Noxus" or "Demacia", however, this doesn't seem to work as it returns an empty array
let regions = ["Demacia", "Noxus"];
let filtered = this.cards.filter((card) => {
return card.region.includes(regions);
})
Can I even do that or do I need to look into other array functions?
Instead of trying to pass multiple options to includes, look inside regions to see if it contains the region of the current card
let regions = ["Demacia", "Noxus"];
let filtered = this.cards.filter((card) => {
return regions.includes(card.region);
})
Just adding my answer because Array.prototype.includes() is not supported in IE, so if you want to support old browser, you can do
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes#Browser_compatibility
let regions = ["Demacia", "Noxus"];
let filtered = this.cards.filter((card) => {
return regions.indexOf(card.region) > -1;
})

removing objects in an object in an array javascript

I've done some research on this issue. I am trying to manipulate an array of calculated values that looks like this in the console:
{nodeVoltages: Array(11), totalPower: Array(1), xlength: Array(11)}
nodeVoltages: Array(11)
0:48
1:47.71306060387108
2:47.250273223993105
3:46.59686907269243
4:45.71876416434013
5:44.53304242029258
6:42.745236969423615
7:Complex {re: 40.38334500994142, im:1.919295696316476, __ember1513267958317: "ember368"}
8:Complex { re:39.55961661806138, im:3.8933604519196416, __ember1513267958317: "ember369"}
This array is created dynamically through some math that I've come up with so there is no input data that I can give you. I'm trying to make the above array look like this:
{nodeVoltages: Array(11), totalPower: Array(1), xlength: Array(11)}
nodeVoltages: Array(11)
0:48
1:47.71306060387108
2:47.250273223993105
3:46.59686907269243
4:45.71876416434013
5:44.53304242029258
6:42.745236969423615
7:40.38334500994142
8:39.55961661806138
Using mathjs, I was able to evaluate my expressions and dynamically add the values into an array with the array.push command and display them. However, my code breaks once the imaginary values pop up in the results of my array.
How can I remove these imaginary numbers from my array? In other words, I need to remove the "im:" parts of the values when they begin to appear before I push them to the displayed array.
I tried to do this with some code I found from a previous answer to someone else's question (How do I remove a particular element from an array in JavaScript?) splice command like this:
var nodeVoltage2 = parser.eval(expression2);
//checks if there are imaginary values and removes them
if ("im" in nodeVoltage2) {
nodeVoltage2.splice(2,1)
}
//adds value to result array for analysis
nodeVoltages.push(nodeVoltage2);
but it returns in the console that "im is not defined".
Any help is greatly appreciated!
You can use the array map function.
Basically, we loop through the array. If the item has a .re property, we take that value only. If there is no .re property, we keep the value as is.
We can either write that in shorthand, as with result using the ternary operator and arrow function, or we can write it in a slightly more verbose but traditional way, as with resultTwo
let data = [
48
,47.71306060387108
,47.250273223993105
,46.59686907269243
,45.71876416434013
,44.53304242029258
,42.745236969423615
,{re: 40.38334500994142, im:1.919295696316476, __ember1513267958317: "ember368"}
,{ re:39.55961661806138, im:3.8933604519196416, __ember1513267958317: "ember369"}
]
let result = data.map((x) => x && x.re ? x.re : x);
let resultTwo = data.map(function(elem) {
// First, we need to check that the array element is not null / undefined
// We then need to check that it has a property called re that is also not null / undefined
if (elem != null && elem.re != null) {
// Just return the property we're interested in
return elem.re;
} else {
// Return the element as is
return elem;
}
});
console.log(result);
console.log(resultTwo);

Javascript filter and match all elements in array

I have an array that looks like:
var testArr = ["40", "A1", "B9", "58"]
I want to loop over all div elements of a certain class and return only the elements where the data attribute matches ANY of the items in that array.
If I do something like this:
$("div.prodCodes").filter(function(e) {
var x1 = $(this);
var x2 = $(this).data("prodCode");
testArr.forEach(function(e) { if (e == x2) { console.log("MATCH"); } });
});
That console outputs the correct number of matches, but I cannot return those elements from the filter function.
What on earth am I missing here? I've tried creating a new array and pushing each item onto it and returning that, but it's always empty. I'm sure I'm missing something obvious here. I've also tried rewriting this using .grep() and getting nowhere. Help is appreciated.
You need to return a truthy value in filter() to have an item included.
Try :
$("div.prodCodes").filter(function(e) {
return testArr.indexOf($(this).attr('data-prodCode')) >-1;
}).doSomething();
Without a return all items will be excluded
I would use a Set for constant-time lookup.
Be aware that jQuery reads the attribute value "58" as a number when using the data method, so it won't match unless you make sure the data type is the same:
// Use a set
var testSet = new Set(["40", "A1", "B9", "58"]);
var texts = $("div.prodCodes").filter(function() {
var x = $(this).data("prodCode").toString(); // data type must match
// Return a boolean to indicate whether the div element should be kept
return testSet.has(x); // Set#has() is fast
}).map(function(){
// For demo only: get the text content of the matching div elements
return $(this).text();
}).get(); // convert that to a plain array
console.log(texts);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="prodCodes" data-prod-code="A1">Hello</div>
<div class="prodCodes" data-prod-code="XX">Not this one</div>
<div class="prodCodes" data-prod-code="58">There</div>

AngularJS / Javascript: Find a string match in a nested object

I have a complex object (a user object) that has nested arrays and nested objects within it.
I have a search filter that is relatively complicated as well (checkboxes determining which items are returned, along with a search input).
Currently I search in an object like so:
for(var key in item){
if(item[key] && item[key].length && String(item[key]).toLowerCase().indexOf($rootScope.filt.searchFilter.toLowerCase()) !== -1){
realSave = true;
}
}
However, this only works for the first layer of objects within an item; I need to also search for objects within objects.
How can i do this? Is this a simpler way than the above? (Note, I can't just use ng-repeat="item in items | searchFilter" as this needs to also parse checkboxes and return values accordingly.
Try
realSave = (JSON.stringify(item).indexOf($rootScope.filt.searchFilter.toLowerCase()) !== -1)
(It's a long line, scroll to the right)
It will transform your whole object into a single string, then you can search for the sub-string you're looking for anywhere inside it.
You can use angular filter like this:
app.controller('MainCtrl', function($scope, $filter) {
$scope.a = [{name : 'pit'}, {name : {a : 'pit'}}, {name : { a : { b : 'pit'}}}];
$scope.find = $filter('filter')($scope.a, 'pit');
});
http://plnkr.co/edit/TenLILkXJ0zwqMVtAj35?p=preview

Compare Objects in Array and Remove Duplicate & Update - Javascript

I have an array of objects that presents as follows:
0: Object
ConsolidatedItem_catalogId: "080808"
ConsolidatedItem_catalogItem: "undefined"
ConsolidatedItem_cost: "0"
ConsolidatedItem_description: "Test Catalog Item"
ConsolidatedItem_imageFile: "27617647008728.jpg"
ConsolidatedItem_itemNumber: "1234"
ConsolidatedItem_quantity: "1"
ConsolidatedItem_source: "CAT"
ConsolidatedItem_status: "02"
ConsolidatedItem_umCode: "EA"
1: Object
ConsolidatedItem_catalogId: ""
ConsolidatedItem_catalogItem: "undefined"
ConsolidatedItem_cost: "0"
ConsolidatedItem_description: "ALARM,SHUTDOWN SYSTEM,AXIOM,XP3, 0-1500 PSIG, HIGH AND LOW PRES Testing"
ConsolidatedItem_imageFile: ""
ConsolidatedItem_itemNumber: "10008"
ConsolidatedItem_quantity: "1"
ConsolidatedItem_source: "INV"
ConsolidatedItem_status: "02"
ConsolidatedItem_umCode: "EA"
I'm trying to update and remove an object if it's added again, or update the object. Preferably update the object with the new value. My code is as follows:
var result = $.grep(finalObject, function(e) {
return e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber;
});
console.log(result);
if (result.length == 0) {
finalObject.push(o);
shoppingCounter = finalObject.length;
$('#numberShoppedItems').text(shoppingCounter);
console.log(finalObject);
} else if (result.length == 1) {
finalObject.filter(function(x){
result = x;
console.log(result);
return x == result.ConsolidatedItem_itemNumber;
});
} else {
alert('Multiples Found');
}
}
I've tried multiple ways of getting the exact object and manipulating the data, however they've all failed. I would prefer to update the object, say if CatalogItem_itemNumber held the same value, if the CatalogItem_quantity was different - add the CatalogItem_quantity values together and update the array of objects.
I don't need an exact answer, a nudge in the right direction would do wonders though. I've looked at several of the related questions over the past couple of hours but none of them seem to address the issue. If you know of a question that has an answer, feel free to just link that as well. I may have missed it.
No Underscore.js please
When you find the matching record, you may update it by using $.extend
$.extend(result[0], o)
This will update the object in finalObject array in-place.
Alternatively, if you want to use the filter, you will need to insert the new object in the array.
finalObject = finalObject.filter(function(x) {
return x !== result[0];
});
finalObject.push(o)
Here we are allowing all the records that are not not equal to result to be returned in the resultant array that is received in finalObject. In next line, we are adding the new record.
Solved in the following manner:
1.) Verify object is not empty.
2.) Use .some() on object to iterate through it.
3.) Check if the finalObject, which is now e, has a match for the key in my temporary object I assemble, o.
4.) Update the values that need updating and return true;
Note: Originally I was going to remove the object by its index and replace it with a new object. This too can work by using .splice() and getting the index of the current object in that array you're in.
Here is the updating version:
if (o.ConsolidatedItem_quantity != '') {
var result = $.grep(finalObject, function(e) {
return e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber;
});
if (result.length == 0) {...}
else {
finalObject.some(function (e) {
if(e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber){
var a;
a = +e.ConsolidatedItem_quantity + +o.ConsolidatedItem_quantity;
e.ConsolidatedItem_quantity = a.toString();
document.getElementById(o.ConsolidatedItem_itemNumber).value=a;
return true;
};
});
}
}

Categories