Negate values from array with OR operator - javascript

This is a very simple question but I am not been able to wrap my head around it.
I have an array of pages with n number of page names, I want to run a loop with some page names not included in it.
var arr = ["page-name", "page-name-two", 'page-3', 'some-more', 'another-page'];
for (var page in arr) {
if (arr[page] !== "page-name" || arr[page] !== "some-more") {
console.log(arr[page])
}
}
Now the result that I want is this:
page-name-two
page-3
another-page
What am I doing wrong?

Just take logical AND && instead of logical OR ||.
Please use a for loop with a variable for the index instead of the keys of an object.
Source:
Why is using “for…in” with array iteration a bad idea?
var arr = ["page-name", "page-name-two", 'page-3', 'some-more', 'another-page'];
for (var i = 0; i < arr.length; i++) {
if (arr[i] !== "page-name" && arr[i] !== "some-more") {
console.log(arr[i]);
}
}
The expression
arr[i] !== "page-name" || arr[i] !== "some-more"
is always true, because for exampe if
arr[i] === "page-name"
then the other part is true, because of
"page-name" !== "some-more"`.

You should use .filter() to filter values from first array and then perform whatever action you want to perform on resultant array. This will save your from writing a lot of OR / AND conditions in case you need to filter more values.
let arr1 = ["page-name", "page-name-two", 'page-3', 'some-more', 'another-page'],
arr2 = ["page-name", 'some-more'];
let result = arr1.filter(s => !arr2.includes(s));
console.log(result);

I would store the values that you're looking to eliminate, then run Array.filter on your list of all page names to find matches. If a name matches, remove it from the final array.
// This can be a array of whatever strings you're looking to eliminate from the array
const valuesToFilter = ['page-name', 'some-more'];
// Your original array
const arr = ["page-name", "page-name-two", 'page-3', 'some-more', 'another-page'];
// Use Array.filter to eliminate anything that doesn't pass the filter test
const filteredArr = arr.filter(page => {
let foundMatch = false;
valuesToFilter.forEach(value => {
if (page === value) {
foundMatch = true;
}
})
if (!foundMatch) return page;
});
console.log(filteredArr);

Related

How could I rename an item in a simple array in Angular

I work on an Angular project and I built an array.
Now I'd like to rename one of the items of the array. I found the way to rename the keys of an array but I still don't know how to do to apply this to its values.
Here is my array below.
I'd like to change 'valueC' by 'valueZ'.
myArray = ['valueA', 'valueB', 'valueC']
I tried the following code :
for (const k in this.myArray) {
if (k == "valueC") {
this.myArray[k] = "valueZ";
}
But it does not work.
Could you help me ?
Any help would be very appreciated, thanks.
Below are two possible methods!
const myArray = ['valueA', 'valueB', 'valueC']
//rename - if index known
myArray[2] = 'valueZ';
console.log('if index known', myArray);
//rename - if index not known
const foundIndex = myArray.findIndex(x => x === 'valueC');
if (foundIndex > -1) {
myArray[2] = 'valueZ';
}
console.log('if index not known', myArray);
Your code just needs a minor correction:
if (this.myArray[k] == "valueC")
Try this:
const myArray = ['valueA', 'valueB', 'valueC'];
for (const k in myArray) {
if (myArray[k] == "valueC") {
myArray[k] = "valueZ";
}
}
console.log(myArray);
You need to track the index, easy with a forEach
this.myArray.forEach((k, index) => {
if (k == "valueC") {
this.myArray[index] = "valueZ";
}
})
My prefered way :
Though, be sure to have the value "valueC" inside the array
otherwise indexOf will return a -1, provoquing an error
// without index control
this.myArray[this.myArray.indexOf("valueC")] = "valueZ";
// with index control
const index = this.myArray.indexOf("valueC")
if (index >= 0) {
this.myArray[index] = "valueZ";
}
Also note this for future usage :)
for (const k in array) : in that case k is the index of elements in array
for (const k of array) : in that case k is the value of elements in array
On top of all the other solutions here, another approach, and one I believe is better in that it gets you in the mindset of immutability, is to return a new object instead of modifying the current one.
Ex:
this.myArray = this.myArray.map(x => {
if(x !== 'valueC')
return x;
return 'valueZ';
});
So map here will return a new array object for us, in this case a string array given your current array is a string array. Another pattern in use here is only checking for the negative case. Instead of having if/else or a chain of them, we know that for all case that aren't 'valueC' we retain their original value and only valueC's value needs to change to valueZ

Simplest vanilla JavaScript way to pair items from a unidimensional array into a multidimensional array?

Currently I have a unidimensional array, e.g. ['thing1', 'cond1', 'thing2', 'cond2', 'thing3']
I would like to pair each item to create a new multidimensional array like so [['thing1', 'cond1'], ['thing2', 'cond2'], ['thing3']]. I don't mind the last item being ['thing3', undefined] – if anything this is preferable unless someone raises this as bad practice.
So far I have
const pair = (arr) => {
let paired = [];
for (i = 0; i < arr.length; i += 2) {
paired.push([arr[i], arr[i+1]]);
}
return paired;
}
You can try this out in my JS Bin example.
This works perfectly fine AFAIA but I'd love this to be as concise as possible using modern JS and I'm not as polished as I should be with my array manipulation.
Thanks in advance to everyone who gives this a go.
Let the challenge... BEGIN!
You could take a while loop with an index variable. For pushing a pair take slice.
const pair = array => {
let paired = [],
i = 0;
while (i < array.length) paired.push(array.slice(i, i += 2));
return paired;
}
var array = ['thing1', 'cond1', 'thing2', 'cond2', 'thing3'],
paired = pair(array);
console.log(paired);
You can try this regex. Group the values by finding the number by using regular expression.
const data = ['thing1', 'cond1', 'thing2', 'cond2', 'thing3'];
const result = {};
data.forEach(value => {
const index = value.replace(/[^\d.]/g, '');
if (typeof result[index] == 'undefined') {
result[index] = [];
}
result[index].push(value);
});
const array = Object.values(result);
console.log(array);

Remove or Filter values out of an Array using for loop or a function

I have an Array and i would like to Filter or delete the following urls from my Array every time they appear:
"https://basueUrl.com/Claim"
"https://basueUrl.com/ExplanationOfBenefit"
My Array
Array= [
"https://basueUrl.com/Patient"
"https://basueUrl.com/Organization"
"https://basueUrl.com/Claim"
"https://basueUrl.com/Practitioner"
"https://basueUrl.com/Encounter"
"https://basueUrl.com/Condition"
"https://basueUrl.com/Claim"
"https://basueUrl.com/ExplanationOfBenefit"
"https://basueUrl.com/Claim"
"https://basueUrl.com/ExplanationOfBenefit"
"https://basueUrl.com/ExplanationOfBenefit"
]
First Solution I have tried for loop but did not work?
for( var i = 0; i < Array.length; i++){
if ( Array[i] === "https://basueUrl.com/ExplanationOfBenefit" & "https://basueUrl.com/Claim") {
Array.splice(i, 1);
i--;
}
}
console.log(Array);
Second Solution I tried making a remove method did not work either.
function arrayRemove(Array, value) {
return Array.filter(function(ele){
return ele != value;
});
}
var result = arrayRemove(Array,"https://basueUrl.com/ExplanationOfBenefit" & "https://basueUrl.com/Claim");
Any suggestion please?
The first approach is modifying the array while the loop is being executed, which generates problem with the index because the array.length changes when you call Array.prototype.splice.
In the second approach, you're not passing what you think
console.log("https://basueUrl.com/ExplanationOfBenefit" & "https://basueUrl.com/Claim");
// A number? probably you want an array.
You can use the function filter and the function includes as follow:
let skip = ["https://basueUrl.com/Claim", "https://basueUrl.com/ExplanationOfBenefit"];
let arr = ["https://basueUrl.com/Patient","https://basueUrl.com/Organization","https://basueUrl.com/Claim","https://basueUrl.com/Practitioner","https://basueUrl.com/Encounter","https://basueUrl.com/Condition","https://basueUrl.com/Claim","https://basueUrl.com/ExplanationOfBenefit","https://basueUrl.com/Claim","https://basueUrl.com/ExplanationOfBenefit","https://basueUrl.com/ExplanationOfBenefit"];
let result = arr.filter(url => !skip.includes(url));
console.log(result);
Array.filter(x => x !== "https://basueUrl.com/Claim" && x !== "https://basueUrl.com/ExplanationOfBenefit")
var Array= [
"https://basueUrl.com/Patient",
"https://basueUrl.com/Organization",
"https://basueUrl.com/Claim",
"https://basueUrl.com/Practitioner",
"https://basueUrl.com/Encounter",
"https://basueUrl.com/Condition",
"https://basueUrl.com/Claim",
"https://basueUrl.com/ExplanationOfBenefit",
"https://basueUrl.com/Claim",
"https://basueUrl.com/ExplanationOfBenefit",
"https://basueUrl.com/ExplanationOfBenefit"
];
var filteredArray = Array.filter(item => item !== "https://basueUrl.com/Claim" && item !== "https://basueUrl.com/ExplanationOfBenefit")
console.log(filteredArray)
You can run the code below. Hope this helps.
// use this array instead on the original. It creates a new array from the original
// array.
const newFilteredArray = Array.filter(url => url !== 'https://basueUrl.com/Claim' &&
url !== 'https://basueUrl.com/ExplanationOfBenefit');
Please see below the way you can achieve the above mentioned scenario.
arr.filter(ele=>ele!=="https://basueUrl.com/Claim"
&& ele!=="https://basueUrl.com/ExplanationOfBenefit");

Selectively push items to an array

So if I had:
A=['a','b','c'];
B=[];
for (var i = 0;i<7;i++){
B.push(A[i])
}
I would get
B=["a", "b", "c", undefined, undefined, undefined, undefined]
Instead I want
B= ["a","b","c"]
So I guess I would need something like
for (var i = 0;i<7;i++){
B.push(A[i] "unless A[i] is undefined. Then don't push anything")
}
How would I do this in Javascript?
Some ES magic
[1, 2, undefined].filter(Boolean)
will produce
[1, 2]
I think this is what you're searching:
Array#filter
B = A.filter(function (element) {
return element !== undefined;
});
That Code will make a duplicate of A filtering out all undefined elements.
Instead of iterating the array and pushing elements one at a time to a new array, it's usually more efficient to use the Array.filter function, like so:
var B = A.filter(function(item){ return item !== undefined; });
You may also want to be cautious about using undefined. This is easily confused with other constructs such as null or empty strings. If you use "!=" instead of "!==" in the function, that will filter out null or missing array items, as well as items which are set specifically as undefined.
You could add a safeguard like
A[i] && B.push(A[i])
which would only push if A1 returns a true, but that would also give false if A[i] would be 0
Example
I would suggest checking against null
if (A[i] != null) B.push(A[i])
Example
If you want to keep your first forloop as it is you can "clean" the array after by using filter. Like:
for (var i = 0; i < 7; i++) {
B.push(A[i])
}
var clean_B = B.filter(function (item) {
return item != null;
});
Example
An Object Oriented Aspect
=> After that code, clean your array :
B.clean();
Known that clean is an extension of array Class(OOP context)
Array.prototype.clean=function(){
var newArray = [];
for(var index = 0; index < this.length; index++) {
if(this[index]) {
newArray.push(this[index]);
}
}
return newArray;
};
You stated the answer to your question in your sort-of comment (use // at the end of the line next time, no need for inserting a comment in a string).
unless A[i] is undefined. Then don't push anything
Another way of putting it is, if A[i] is not undefined, then push.
When put like that, it directly translates into code.
if (A[i] !== undefined)
{
B.push(A[i]);
}
I elaborated on your comment to show you how easily you can figure these types of questions out with a little effort and time.
However, as others have stated, a much better way of ignoring undefined indices is to simply iterate to A.length, however this only works if there are no undefined values in-between the defined values (which is still likely the case).
Your problem would be solved by iterating from 1 to array.length, or by using a for in loop
If you're going to be dealing with arrays that could have undefined elements, for example [0, undefined, 4], then you'd need to check if the element is defined before you add it. if(a[i] !== undefined) will do the trick.
You would use an if statement
for (var i = 0; i < 7; i++){
if (A[i] !== undefined) {
B.push(A[i]);
}
}
You can have a compact function to filter out undefined values:
function compact(col) {
return col.filter(function(val) {
return val !== undefined;
});
}
console.log(compact([false,0,1,null,undefined])); // [false,0,1,null]
JS Bin Example
http://jsbin.com/mabowana/4/edit
initials:
A = ['a', 'b', 'c'];
B = [];
I think, the closest answer to OP's question would be this:
for (var i = 0; i < 7; i++) {
if (typeof A[i] !== "undefined") B.push(A[i]);
else continue;
}
or this one:
for (elem of A) if (typeof elem !== "undefined") B.push(elem); else continue;
Instead of hard coding i < 7, use i < A.length
for (var i = 0; i < A.length; i++){
B.push(A[i])
}

Remove array element when subarray has certain values

I have an array that contains any number of subarrays, each containing exactly two values.
i.e: interestArray[[1, 5], [3, 8] ... ]
How do I remove say the subarray containing the values [3, 8]?
My code is:
$('td', container).click(function(){
if(!$(this).hasClass('purchased') && !$(this).hasClass('manu'))
{
var manuId = $(this).parent().children('td:first-child').data('manu-id');
var typeId = $(this).data('type-id');
if($(this).hasClass('interest'))
{
$(this).removeClass('interest');
$(this).parent().children('td.manu').removeClass('interest');
var index = interestArray.indexOf([manuId, typeId]);
interestArray.splice(index, 1);
} else {
$(this).addClass('interest');
$(this).parent().children('td.manu').addClass('interest');
interestArray.push([manuId, typeId]);
}
//updateSurvey(interestsArray);
console.log(interestArray)
}
})
The below section does not work, and simply removes the first subarray.
var index = interestArray.indexOf([manuId, typeId]);
interestArray.splice(index, 1);
Here's a generic approach with your requirements:
var arr = [[1,2],[3,4],[5,6]];
var remove = [3,4];
for (var i=0; i<arr.length; i++) {
if (arr[i][0] == remove[0] && arr[i][1] == remove[1]) {
arr.splice(i, 1);
break;
}
}
console.log(arr); //=> [[1,2],[5,6]]
For a general approach, you can filter the array:
var reducedArray = interestArray.filter(function (item) {
return item[0] != manuId || item[1] != typeId;
});
You cannot use indexOf because that looks for the identical object (not merely an equivalent one).
If you're running an earlier version of JS that doesn't have Array.filter, there's a nice shim on the filter doc page linked to above.
Here is my personal solution more complete to avoid multiple entry issue and the break; thing seen above, it also avoids an issue if the array is after entry removal (it is jquery based but you can make a regular loop if you feel more comfy with it):
$.each( answers, function( index, value ){
if (typeof answers[index] != "undefined")
{
if(answers[index]["question_id"]==answer_to_del)
{
delete answers[index];
}
}
});
//Clean answer array from empty values created above
answers = answers.filter(function(n){ return n != undefined });

Categories