JS Array not selecting correct values - javascript

I am trying to select items from array using slice() method but it is not selecting right values.
var alphabets = ["A", "B", "C", "D", "E"];
var show = alphabets.slice(1, 2);
console.log(` ${show} `);
It should output B, D but it is giving only: B
Array starting from zero B is 1 and from end D is 1
In other example.
var alphabets = ["A", "B", "C", "D", "E"];
var show = alphabets.slice(1, 3);
console.log(` ${show} `);
Above code output: B,C
How this is even selecting elements?

The slice() method selects the elements starting at the given start argument, and ends at, but does not include, the given end argument.
var alphabets = ["A", "B", "C", "D", "E"];
var show = alphabets.slice(1, 3);
console.log(` ${show} `);
Take your example, "D" is at position 3 so it will not include "D" in your output. It will only give "B" and "C" in your output.

The slice() method returns a shallow copy of a portion of an array into a new array object selected from begin to end (end not included). The original array will not be modified.
arr.slice([begin[, end]])
begin Optional
Zero-based index at which to begin extraction.
end Optional
Zero-based index before which to end extraction. slice extracts up to but not including end.
var animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2));
// expected output: Array ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4));
// expected output: Array ["camel", "duck"]
console.log(animals.slice(1, 5));
// expected output: Array ["bison", "camel", "duck", "elephant"]
If you have questions about JavaScript the Mozilla Developer Network (MDN) is a great place to go.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

This is the working principle of slice:
slice(start,end)
start is the start index and it starts from 0.
end is the end index, but does not include
In your case:
A ---> index 0
B ---> index 1
C ---> index 2
D ---> index 3
E --->index 4
Thus, slice(1,2) will return only index "1" which is B

Please refer to the documentation of Array.prototype.slice, as you have not used the second argument correctly.
The slice() method returns a shallow copy of a portion of an array
into a new array object selected from begin to end (end not included).
The original array will not be modified
Refer to MDN/JS/Array/slice

slice() returns a copy of the array starting for the first index until a second index (NOT INCLUDED). If you want to start counting from the end on the second value you must use a negative index.
var alphabets = ["A", "B", "C", "D", "E"];
var show = alphabets.slice(1, 3);
console.log(` ${show} `);
This will display BC
as well as:
var alphabets = ["A", "B", "C", "D", "E"];
var show = alphabets.slice(1, -2);
console.log(` ${show} `);

The slice() method returns the selected elements in an array, as a
new array object.
The slice() method selects the elements starting at the given start
argument, and ends at, but does not include, the given end argument.
see the below example with same array.
var alphabets = ["A", "B", "C", "D", "E"];
console.log(alphabets .slice(2));
// expected output: Array ["C", "D", "E"]
console.log(alphabets .slice(2, 4));
// expected output: Array ["C", "D"]
console.log(alphabets .slice(1, 5));
// expected output: Array ["B", "C", "D", "E"]

Related

sort function unexpected behaviour

i am trying to understand array sorting method , the problem i am currently facing is when i am declaring some variables inside compare function its not sorting the same as it is doing without those variables although those variables are not used anywhere
can anyone explain what is actually happening here
also i find out that sort functions behave different in firefox and chrome
page_link i am testing this in firefox dev edition
let list1 = ["a","b","c","d","e","f","g","h","i"]
list1.sort((a,b)=>{
let pat = ["d","a"]
return b - a
})
console.log(list1) // Array(9) [ "a", "b", "c", "d", "e", "f", "g", "h", "i" ]
let list2 = ["a","b","c","d","e","f","g","h","i"]
list2.sort((a,b)=>{
// let pat = ["d","a"]
return b - a
})
console.log(list2) // Array(9) [ "i", "h", "g", "f", "e", "d", "c", "b", "a" ]
If you do "a" - "b" it evaluates to NaN which is incorrect as that's not what you intended and also inconsistent (varies browser to browser).
Either don't pass a callback to sort in which case it does the following:
The sort() method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.
Or you can use String.prototype.localeCompare
let list = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
console.log([...list].sort());
console.log([...list].sort((a, b) => a.localeCompare(b)));
If you want to prepend some values to the sorted array you'll have to do it separately you can't do it using sort.
let list = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
let pat = ["x", "y"];
let sortedList = [...list].sort();
let patAppendedSortedList = [...pat, ...sortedList];
console.log(patAppendedSortedList);
And if you want to sort both the list and pat but you want to keep all pat elements before all list elements then consider the snippet below.
let list = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
let pat = ["z", "x", "y"];
let patSet = new Set(pat);
let sortedList = [...pat, ...list].sort((a, b) => {
// If a has higher priority put it before b
if (patSet.has(a) && !patSet.has(b)) {
return -1;
}
// If b has higher priority put it before a
if (patSet.has(b) && !patSet.has(a)) {
return 1;
}
// Otherwise both a and b have same priority
// Sort them according to their value
return a.localeCompare(b);
});
console.log(sortedList);
If you subtract a string from another string, it will attempt to convert the strings to numbers.
All of your strings will convert to NaN.
NaN-NaN is also NaN.
So it doesn't matter which two values from your array you are comparing, your comparison function will always return NaN.
(Note that a comparison function is supposed to return a number that is 0, greater than 0 or less than 0 and be consistent for any given pair of values. The one you are using is just broken for the data you are using).
The order the letters get sorted into therefore depends on the order in which they are compared to each other (because your comparison function is broken).
That order is determined by the sort algorithm that the JS engine uses. This is an implementation detail that the specification doesn't mandate.
One browser might use a quick sort while another might use a bubble sort. Hence you get different results.
Write a comparison function which isn't nonsense to get consistent results.
The default comparison function is find for lexical sorting under most circumstances.
Now i understood your goal. But you cant archive this with your way. You cant make some prepends of values in the JS sort function. You have to make it in two steps. 1.) sort 2.) prepend your pat values to the sorted array.
const list = ["a","b","c","d","e","f","g","h","i"];
const pat = ["d","a"];
const sorted = [...pat, ...list.sort()];
console.log(sorted)

Remove first occurence of an element using JavaScript or Lodash

I have an array like this -
["a", "a", "b", "c", "d", "e"]
I want to operate on this and filter it to remove only the first occurence of every element in the array.
The output in the above case is expected to be - ["a"]
How can I achieve this using JavaScript or Lodash?
By wanting the first one of duplicate following items, you could use Array#lastIndexOf along with a check of the actual index.
const
data = ["a", "a", "b", "c", "d", "e"],
result = data.filter((v, i, a) => i !== a.lastIndexOf(v));
console.log(result);
You can use an empty object as a map to easily check if the item has been found before and then use Array#filter to remove the ones you don't want.
var list = ["a", "a", "b", "c", "d", "e"];
var occurences = {};
var filteredList = list.filter(function(item) {
if (item in occurences) return true; // if it has already been registered, add it to the new list
occurences[item] = 1; // register the item
return false; // ignore it on the new list
});
console.log(filteredList);
Shorthand version
let list = ["a", "a", "b", "c", "d", "e"], occurences = {};
list = list.filter(item => item in occurences ? 1 : occurences[item] = 1 && 0);
console.log(list);
you can simply use shift method checkout it here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift

JavaScript arrays and understanding arr[arr.length]

What is meant by arr[arr.length]. I mean what it really means or what it really does, I cannot understand the logic of how it works. Can anybody explain?
arr.length means the length of the array that spans from index 0 to arr.length - 1.
For instance if you got arr = ["a", "b", "c"], arr.length is 3.
arr[0] is "a", arr[1] is "b" and arr[2] is "c".
arr[3] does not exist, yet. but if you do arr[arr.length] = "d", you obtain ["a", "b", "c", "d"].
This is an odd construction and usually, one should simply write arr.push("d").
const arr = ["a", "b", "c"];
console.log(arr.length, arr[0], arr[1], arr[2], arr[3]);
arr[arr.length] = "d";
console.log(arr);
arr.push("e");
console.log(arr);
This statement gets the index of the last index of the array plus one. It is used to append items to an array. Equivalent to array.push().
var fruits = ["apple", "orange", "banana", "pear"];
// appends grapes to the array
fruits[fruits.length] = "grapes";
console.log(fruits);
For further reading, check out MDN's page on array methods.
arr.length is the length of the array.
arr[arr.length] is accessing by index the array length (out of bounds as length starts at 1, not index 0).
example:
const test = [1,2,3]
test[test.length]
undefined
test[test.length-1]
3
It just requests specific index of the array, Use case: Not very elegant way of adding new element to the array, like:
arr[arr.length] = newVal
arr.push(newVal)
arr = [...arr, newVal]

How does one merge and compute array items within a nested array structure via a fixed condition/rule

I have an JavaScript heterogenous array of arrays which looks like :
let bigArray = [["A", "B", 221.67],["C", "B", 221.65],["B", "D", 183.33],["B", "A", 4900],["E", "B", 150],["A", "B", 150]]
Now i want to add the 3rd element(number) if the first and second elements matches with the first and second element of next array(in multidimensional array), then add 3rd element(number) of both array & also perform minus operation if reverse of those elements match is found.
Output will be:
let ans = [["B", "A", 4528.33],["C", "B", 221.65],["B", "D", 183.33],["E", "B", 150]]
sub array ["B","A", 4528.33] is formed by performing minus operation, i,e 4900-221.67-150
In bigArray there are array with repeated pair of elements like "A" & "B"(in single sub array). So for all matching subarrays perform sum operation & if reverse of that matching sub array is found then perform minus operation. i,e=> 4900-221.67-150
I tried many methods but cant able to achieve the desired output for all the cases. Any help will be appreciated, Thanks
You could group with sorted keys to maintain a standard key and check if the part keys have the same order, then add the value or subtract.
If a value is negative change the keys and take a positive value.
let data = [["A", "B", 221.67], ["C", "B", 221.65], ["B", "D", 183.33], ["B", "A", 4900], ["E", "B", 150], ["A", "B", 150]],
result = Object.values(data.reduce((r, [a, b, v]) => {
const key = [a, b].sort().join('|');
if (r[key]) {
r[key][2] += a === r[key][0] ? v : -v;
if (r[key][2] < 0) r[key] = [r[key][1], r[key][0], -r[key][2]];
} else {
r[key] = [a, b, v];
}
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Join Array from startIndex to endIndex

I wanted to ask if there is some kind of utility function which offers array joining while providing an index. Maybe Prototype of jQuery provides this, if not, I will write it on my own :)
What I expect is something like
var array= ["a", "b", "c", "d"];
function Array.prototype.join(seperator [, startIndex, endIndex]){
// code
}
so that array.join("-", 1, 2) would return "b-c"
Is there this kind of utility function in an pretty common Javascript Library?
Regards
globalworming
It works native
["a", "b", "c", "d"].slice(1,3).join("-") //b-c
If you want it to behave like your definition you could use it that way:
Array.prototype.myJoin = function(seperator,start,end){
if(!start) start = 0;
if(!end) end = this.length - 1;
end++;
return this.slice(start,end).join(seperator);
};
var arr = ["a", "b", "c", "d"];
arr.myJoin("-",2,3) //c-d
arr.myJoin("-") //a-b-c-d
arr.myJoin("-",1) //b-c-d
Just slice the array you want out, then join it manually.
var array= ["a", "b", "c", "d"];
var joinedArray = array.slice(1, 3).join("-");
Note: slice() doesn't include the last index specified, so (1, 3) is equivalent to (1, 2).

Categories

Resources