I have one array something like following:
$scope.blinkedBoxes=[3,4,1,2,..]
It will have upto 8 elements in total (elements will be one of the numbers from 1,2,3,4).
Another array is like following:
$scope.clickedImages=[2,4,3,1,...]
I am building following function:
$scope.checkCrossCorrectness = function(array1, array2){}
My requirement is:
If the first element of $scope.blinkingBoxes is 2 (or basically any from 1, 2, 3, 4) then in $scope.clickedImages first element can not be 2 (or same as first element of first array), instead could be 1, 3, or 4.
This logic continues for further elements as well (i.e. in first array at second position if 3 comes then in second array second position can be occupied by either 1, 2 or 4)
How can I implement this?
I dont really know if this has anything to do with angular specifically, but from what I can tell a simple forEach loop will do to check equality between the indexes.
Example:
$scope.blinkedBoxes = [1, 2 ..] // etc
$scope.clickedImages = [2, 1, ..] // etc
function functionToRunOnClickOrWhatever(){
$scope.blinkedBoxes.forEach(function(val, index){
var isEqual = val === $scope.clickedImages[index];
if(isEqual){
// do something?
}
});
}
Related
In the following example, splice().splice() didn't work. What am I missing? How can I chain two splice methods in a single line? Thank you for any advice!
function test() {
var data = [0,1,2,3,4,5];
data.splice(0,2).splice(-1); // Removed only the first two elements, but not the last element.
console.log(data) // Returned [ 2, 3, 4, 5 ]
var data = [0,1,2,3,4,5];
data.splice(0,2); // Removed the first two elements.
data.splice(-1); // Removed the last element.
console.log(data) // Returned [ 2, 3, 4 ]
}
splice returns the removed elements, so chaining them in a single statement won't really work - you don't want to operate on the removed elements, you want to operate on the original array both times.
Usually, in this sort of situation, the right approach is to use slice instead, which is both easier to work with (just specify a start (inclusive) and end (exclusive) index) and is more functional (you get a new array instead of mutating an existing one - it's nice to avoid mutation when possible, makes code more understandable).
const data = [0,1,2,3,4,5];
console.log(data.slice(2,5));
You can do this, although I don't recommend this because it makes the code confusing
const data = [0,1,2,3,4,5];
console.log(data.splice(2,4).splice(0,3)); // Returned [2,3,4]
consider this code
example 1:
function plus(a) {return a+10}
([1]) // "110"
example 2:
var arr = [1,2,3,4,5,6,7]
arr[[1]] // 2
arr.splice([1],1);
arr // (6) [1, 3, 4, 5, 6, 7]
can someone explain why passing in an array as an argument, gets converted to a string? (that's what it looks like happened here)
can someone explain why passing in an array as an argument
It doesn't.
It gets treated as an array right up until the point where you try to use the addition operator on it.
It hits the step Let rprim be ? ToPrimitive(rval) and converts it according to those rules.
And so on until it calls the array's toString method.
Similar rules apply in the other examples.
In short: When it makes no sense at all to use an array in a given context, type conversion is applied to turn it into a data type that is apropriate.
Javascript automatically outputs a certain data type when two different data types are added.
Here are two examples:
2 + 3 // 5
2 + "hello" // "2hello"
When two numbers are added, an integer is output. However, 2 and hello can't be added numerically, so everything is first automatically converted to a string, and then appended.
The same thing happens in your case – a remains an array, but an array can't be added to a number. So both are converted to strings and then appended, and the end result is a string.
You were probablly thinking of adding a value to the end of an array. This is done using:
a.push(10);
Or, if you wanted to add the first item in the array and 10 to get the result 11, use:
return a[0] + 10
But you can't add a single number to a whole array, only to one of the items or at the end of the array.
Answer #1 - you get a string from the array.toString so you need to cast back to number - here I use +
function plus(a) {return +a+10}
console.log(plus([1]))
Second
var arr = [1,2,3,4,5,6,7]
console.log(arr[1]) // 2
console.log(arr[[1]]) // 2
arr.splice([1],1); // removes the second item
console.log(arr)
var arr = [1,2,3,4,5,6,7]
arr.splice(1,1); // just as if you had done this
console.log(arr) // [1, 3, 4, 5, 6, 7]
The + operator doesn't work for arrays. It only works for numbers or strings.
Since javascript can't use your array with the + operator, it converts it to string before. That's why plus([1]) is "110"
You can use the push method if you want to add to an array:
array.push(newElement);
In the second example, inside splice, your array is used with an operator that doesn't support it so it is converted to a number. If you look at the MDN definition of splice, you see it expects a number, not an array.
When you want to use splice, you don't pass an array as the first argument, you pass the index of the first element to remove. If you want to remove 2 from your array, you do arr.splice(1,1);
Now I would like to flattening the array with multiple layers
From the other solution before and the developer's network, There is an effective solution:
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
function flattenDeep(arr1) {
return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
}
flattenDeep(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
However, there is a couple questions about the theory at that back that I want to ask:
1. In my understanding, the function starts with initial value acc, and then it keeps looping all the element to see if it is an array or not.
In this case, the first 3 elements are 1,2,3 -- therefore is not an array and will be accumulated and returned as an array.
But start from the fourth element it returns
Array.isArray(arr1[3])
(5) [1, 2, 3, 4, Array(3)]
In this case, it triggers the condition acc.concat(flattenDeep(val)), which is a recursion of the function. How this condition helps to flatten the array?
And for the [] at the back, if my understand is right, it indicates the return form of the result from reduce should be an array?
Last but not least, any good reference for this topics that I should look for?
May thanks for your help!
Further elaboration:
let's say, now the val in the reduce function above is [1, 2, 3, 4,[[2,3,4]]].
In this first round of checking, the elements 1,2,3,4 are not array, but the last element still does, and it makes the whole argument still an array. For the next round of the recursion, would it just take the element [[2,3,4]]] and further evaluate the elements inside this array?
Or with this example, what would be the first, second and third round outcome of the recursion process?
Second argument in the reduce method is the starting condition. If there is nothing provided, first acc will be the first array's element (see array.prototype.reduce on mdn).
I'm not sure about the But there is nth to indicate the reduction of the array statement. You're calling function recursively until you will find something that's not an array and then you're returning that value.
Look for js call stack, understand how js is stacking the functions, you can even draw it, it will help definitely because it's not easy case :)
For a reason specific to this application an array of data or nulls is used to display a list of forms. The difference is based on whether data was provided by a service or manually added, where null indicates everything was manually added via
a button not a service.
So ignoring the use case of an array of nulls it turns out that [null, null, null].splice(0, 1); removes the null at index 2 instead of 0 based on entering values into the different forms displayed based on the array length, and then seeing who disappears on delete.
It can be made to work by adding something unique like { index: theIndex } to the array instead of null. So splice now works correctly removing the item at index 0 instead of 2, but now I'm curious what splice does under the covers that it can't remove an index regardless of its value compared to the other indices.
Can anyone explain what splice is doing? Based on the spec for splice I don't really see why this happens.
(This follows from the comments in the question but is too large to be a comment).
So I think you are having a conceptual misconception (^^). Look at this examples:
let a = [1, 2, 3]
a.splice(0, 1) // => 1
a // => [2, 3]
let b = [1, 2, 3]
delete b[0] // => true
b // => [<1 empty slot>, 2, 3]
The splice function modifies the array in-place. Note that, although we spliced the first element, we got as a result an array of two elements.
Look now at this example
let a = [1, 1, 1]
a.splice(0, 1)
a // => [1, 1]
let b = [1, 1, 1]
b.splice(2, 1)
b // => [1, 1]
We are deleting the first element from a and the last from b, but of course there's no way of telling so just looking at the result.
In the case with the nulls, the same thing is happening. Some library (Angular) is trying to figure out which element you deleted, but there's no way of knowing. This is because null === null.
Now if you use an array of empty objects, for example, there would be a way of knowing. Since {} !== {}---because each time you cast a {} you are creating a unique object---, then you could know which element is missing in an array of empty objects. The case is similar with the array [1, 2, 3].
let a = [{}, {}, {}] // lets imagine that each object has a unique id
// and we have [{}#1, {}#2, {}#3]
let [obj1, obj2, obj3] = a
obj1 === obj2 // => false, because they have different ids.
a.splice(0, 1)
a // => [{}#2, {}#3]
a.includes(obj1) // => false, because {}#1 is no longer in a
So an alternative to using an array of nulls, would be to use an array of empty objects. I think that is why the code works for you when you use objects like { index: theIndex }. But of course all depends on how smart Angular is. I bet there is a more native way of deleting an element, as #KaiserKatze points out, "it's always a bad idea to directly remove or add elements in the array if it maps to your model."
You have to understand that when you are splicing the array you're only doing that--removing an element from an array. You're not removing the "form element" when splicing the array. Instead, some foreign code is reading the array and trying to figure out --under the hood-- what you intended to do.
Kinda wierd but i have an array
var array = [ 1, 2, 3, 4];
and if i do array.splice(1);
it removes the 2 , 3 and the 4?
how do I remove only the 2 and leave both 3 and 4 as is?
so it would be var array = [ 1, 3, 4]; ?
You have to tell splice how many elements to remove:
array.splice(1,1); # start at index 1, remove 1
I am not sure if the form you used without that parameter is a standard, actually. It could be a browser-specific (Firefox/Spidermonkey) extension.
You can add even more parameters. Those will be elements to replace the removed elements with.
It's a versatile function, take a look at the documentation.
Function splice takes two or more arguments.
The first argument means the index of the first item to be removed.
The second argumemt means the number of items to be removed.
The third and after are data to replace removed items.
Your code lacks the second argument, so splice function removed all items after the index which is specified by first argument.
array.splice(1,1);
will remove only one item at index 1, so [1,2,3,4] becomes [1,3,4].