Adding library function for sorting array gives undefined - javascript

I am trying to add a Library function for sorting Items in an array. Though I got link and way, but when trying to make a library function, this doesn't work. can someone help me out as it is responding undefined as result.
var arr1 = [5, 4, 2, 6, 9, 2, 8, 1, 6];
Array.prototype.sortItems = function(){
this.sort((a,b) => a - b);
}
console.log(arr1.sortItems());
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

you need to return the result of this.sort()
var arr1 = [5, 4, 2, 6, 9, 2, 8, 1, 6];
Array.prototype.sortItems = function(){
return this.sort((a,b) => a - b);
}
console.log(arr1.sortItems());
.as-console-wrapper { max-height: 100% !important; top: 0; }

Try returning the result
var arr1 = [5, 4, 2, 6, 9, 2, 8, 1, 6];
Array.prototype.sortItems = function(){
return this.sort((a,b) => a - b);
}
console.log(arr1.sortItems());
FYI, compareFunction is optional
var arr1 = [5, 4, 2, 6, 9, 2, 8, 1, 6];
console.log(arr1.sort());

Related

compare 2 arrays and check the positions

I have 2 arrays, one has 10 elements and the other one 3, I need to create a new array with the same size of the biggest vector, with a boolean checking true in the position where exist some element from the array of 3 elements
I have the following arrays
array1 = [1,2,3,4,5,6,7,8,9,10]
array2 = [4,6,10]
I tried making 2 for loops
for(var i=0; i<array1.lenght; i++){
for(var j=0; i<array2.lenght; i++){
if(array1[i]==array2[j]){
array3.push(true)
}else{
array3.push(false)
}
}
}
the vector that I need would be
array3 = [false, false, false, true, false, true, false, false, false, true]
You can forEach first array and use include method to check if item existed in array as
let array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let array2 = [4, 6, 10];
let array3 = [];
array1.forEach(function (c) {
if (array2.includes(c)) {
array3.push(true)
} else {
array3.push(false);
}
})
console.log(array3)
Use map like so with shift like so:
const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const array2 = [4, 6, 10];
const array3 = array1.map(e => {
if (array2[0] == e) {
array2.shift();
return true;
}
return false;
});
console.log(array3);
.as-console-wrapper { max-height: 100% !important; top: auto; }
If you just want a basic check as for whether the element is in the array, not the order, then use includes.
const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const array2 = [4, 6, 10];
const array3 = array1.map(e => array2.includes(e));
console.log(array3);
.as-console-wrapper { max-height: 100% !important; top: auto; }
You can also instead of another array use a Set and then Array.map the first away checking if the value is in the Set:
let array1 = [1,2,3,4,5,6,7,8,9,10],
set = new Set([4,6,10])
let result = array1.map(x => set.has(x))
console.log(result)
I would suggest to keep things simple and to use Array#indexOf method to determine if array contains another element.
const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const array2 = [4, 6, 10];
const b = array1.map(el => {
return array2.indexOf(el) !== -1;
});
console.log(b);
const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const array2 = [4, 6, 10];
const finalArray = [];
for (let data of array1) {
finalArray.push(array2.includes(data));
}

Check if the sub set of numbers is in starting part of the series or bottom part of the series using jQuery or javascript

For example: I have set 1,3,4,5,6,7,8,10,11
scenario 1 : subset = 1,3,4 which is in starting part of the series = Acceptable
scenario 2 : subset = 8,10,11 which is in ending part of the series = Acceptable
scenario 3 : subset = 1,3,10,11 which is in both starting and ending part of the series = Acceptable
scenario 4 : subset = 1,3,6,8 which is in starting part of series and also in the middle of the series = Not Acceptable.
Main thing to achieve is to check if the given series is in starting part of the series or ending part without breaking the series using jquery or javacript
Help will be much appreciated
Thanks in advance
You could use a two pass approach, with first collecting for all subarray items the comparison at the same index from start and end (later denoted as left and right side).
To indicate a result, 4 states are returned which mean
0 - no match, neither from the left nor from the right side matches the value,
1 - item of the left side of the array matches,
2 - item of the right side of the array matches,
3 - item matches on both sides.
After collecting the values which represent match and position, the values have to be consolidated to the wanted result, true or false.
To check each value, you need another value which represents the expected side. At start, the expected side is set to 1, because it starts at the left side to check.
The temporary result of the callback with Array#every is a single check if the actual value is greater or equal to the expected value. This includes indicator 3 because this value is in both sides. A value of zero exits the loop as well.
If a value of 2 is found, then it indicates the right side and all following elements have to be greater than 2, therefor the expected value is set to 2.
The presented solution could be shortened to just return the wanted boolean value.
function check(array, subarray) {
var expected = 1,
temp = subarray.map(function (a, i) {
var offset = array.length - subarray.length;
return (a === array[i]) + 2 * (a === array[i + offset]);
}),
result = temp.every(function (a) {
var r = a >= expected;
if (a === 2) {
expected = 2;
}
return r;
});
return temp.concat(result);
}
var array = [1, 3, 4, 5, 6, 7, 8, 10, 11];
console.log(check(array, [1, 3, 4])); // true
console.log(check(array, [8, 10, 11])); // true
console.log(check(array, [1, 3, 10, 11])); // true
console.log(check(array, [1, 3, 6, 8])); // false
console.log(check([1, 2, 3, 4, 5, 6], [1, 4, 3, 6])); // false
console.log(check([1, 2, 3, 4, 5, 6], [1, 4, 3, 6])); // false
console.log(check([1, 2, 3, 2, 3, 4], [3, 2, 3, 2])); // false
console.log(check([1, 2, 3, 2, 3, 4], [1, 2, 3, 4])); // true
.as-console-wrapper { max-height: 100% !important; top: 0; }
The short version without a temporary array.
function check(array, subarray) {
var offset = array.length - subarray.length,
expected = 1;
return subarray.every(function (a, i) {
var state = (a === array[i]) + 2 * (a === array[i + offset]),
result = state >= expected;
if (state === 2) {
expected = 2;
}
return result;
});
}
var array = [1, 3, 4, 5, 6, 7, 8, 10, 11];
console.log(check(array, [1, 3, 4])); // true
console.log(check(array, [8, 10, 11])); // true
console.log(check(array, [1, 3, 10, 11])); // true
console.log(check(array, [1, 3, 6, 8])); // false
console.log(check([1, 2, 3, 4, 5, 6], [1, 4, 3, 6])); // false
console.log(check([1, 2, 3, 4, 5, 6], [1, 4, 3, 6])); // false
console.log(check([1, 2, 3, 2, 3, 4], [3, 2, 3, 2])); // false
console.log(check([1, 2, 3, 2, 3, 4], [1, 2, 3, 4])); // true
.as-console-wrapper { max-height: 100% !important; top: 0; }
You would iterate through the subarray from left to right, and from right to left, and stop where the value does not match with the value in the main array at the "corresponding position", i.e. the position counting from the same side of the array.
If at the end of both loops all values of the subarray matched, i.e. the two indexes crossed each other, then the result is true.
Here is the code:
function isSubsetAtEnds(array, subarray) {
const diff = array.length - subarray.length;
let i, j;
if (diff < 0) return false;
for (i = 0; i < subarray.length; i++)
if (array[i] !== subarray[i]) break;
for (j = subarray.length - 1; j >= i; j--)
if (array[j+diff] !== subarray[j]) break;
return j < i;
}
var array = [1, 3, 4, 5, 6, 7, 8, 10, 11];
console.log(isSubsetAtEnds(array, [1, 3, 4])); // true
console.log(isSubsetAtEnds(array, [8, 10, 11])); // true
console.log(isSubsetAtEnds(array, [1, 3, 10, 11])); // true
console.log(isSubsetAtEnds(array, [1, 3, 6, 8])); // false
One simple approach: remove matching numbers from the beginning and end of both arrays, and see if there are any leftovers.
var checkIt = function(arr,subarr) {
// strip off matching numbers at the beginning
while (subarr.length && arr[0] === subarr[0]) {
arr.shift();
subarr.shift();
}
// strip off matching numbers at the end
while (subarr.length && arr[arr.length - 1] === subarr[subarr.length - 1]) {
arr.pop();
subarr.pop();
}
// if there aren't any leftovers, return true
return (subarr.length === 0)
}
console.log(checkIt( [1, 3, 4, 5, 6, 7, 8, 10, 11],[1, 3, 4]));
console.log(checkIt( [1, 3, 4, 5, 6, 7, 8, 10, 11],[8, 10, 11]));
console.log(checkIt( [1, 3, 4, 5, 6, 7, 8, 10, 11],[1, 3, 10, 11]));
console.log(checkIt( [1, 3, 4, 5, 6, 7, 8, 10, 11],[1, 3, 6, 8]));
// pathological edge case:
console.log(checkIt( [1,2,3,2,1],[1,2,3,2,1] ))
// This returns true, but based on the rules of the puzzle I'm honestly not sure whether that's correct.

How can I change the position of a particular item in an array?

I'm trying to change an item's index position in an array, but I cannot figure out a way.
{
"items": [
1,
3,
2
]
}
You can use splice to move an element in an array:
var arr = [
1,
3,
2
];
var oldIndex = 2,
newIndex = 1;
arr.splice(newIndex, 0, arr.splice(oldIndex, 1)[0]);
This makes [1, 2, 3]
The internal splice removes and returns the element, while the external one inserts it back.
Just for fun I defined a generic function able to move a slice, not just an element, and doing the computation of the index:
Object.defineProperty(Array.prototype, "move", {
value:function(oldIndex, newIndex, nbElements){
this.splice.apply(
this, [newIndex-nbElements*(newIndex>oldIndex), 0].concat(this.splice(oldIndex, nbElements))
);
}
});
var arr = [0, 1, 2, 7, 8, 3, 4, 5, 6, 9];
arr.move(5, 3, 4);
console.log('1:', arr) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var arr = [0, 1, 2, 7, 8, 3, 4, 5, 6, 9];
arr.move(3, 9, 2);
console.log('2:', arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var arr = [0, 1, 2, 4, 5, 3, 6, 7];
arr.move(5, 3, 1);
console.log('3:', arr); // [0, 1, 2, 3, 4, 5, 6, 7]
var arr = [0, 3, 1, 2, 4, 5, 6, 7];
arr.move(1, 4, 1);
console.log('3:', arr); // [0, 1, 2, 3, 4, 5, 6, 7]
JS Bin
If you want to sort them in Unicode order (where numbers become strings) you can use sort() function.
items.sort();
If you have your custom order, you need to provide a sort function to the sort function.
function compare(a, b) {
if (a is less than b by some ordering criterion) {
return -1;
}
if (a is greater than b by the ordering criterion) {
return 1;
}
// a must be equal to b
return 0;
}
and you use it like this:
items.sort(compare(a, b));

underscore or lazy.js map (0,1,2,3,4) + (1,2,3,4,5) ->(1,3,5,7,9)

I want to map a sequence to another sequence such as
map (0,1,2,3,4) + (1,2,3,4,5) -> (1,3,5,7,9)
How to do that in lazy.js or underscore ?
Thanks!
You can use _.zip and _.map, like this
var _ = require("underscore");
function sum(numbers) {
var result = 0;
for (var i = 0; i < numbers.length; i += 1) {
result += numbers[i];
}
return result;
}
console.log(_.map(_.zip([0, 1, 2, 3, 4], [1, 2, 3, 4, 5]), sum))
// [ 1, 3, 5, 7, 9 ]
Since only two numbers are going to be there, always, you can simplify that like this
var result = _.chain([0, 1, 2, 3, 4])
.zip([1, 2, 3, 4, 5])
.map(function(numbers) {
return numbers[0] + numbers[1];
})
.value();
console.log(result);
You can make it a little more generic and clean, like this
function sum(numbers) {
return numbers.reduce(function(result, current) {
return result + current;
}, 0);
}
var result = _.chain([0, 1, 2, 3, 4])
.zip([1, 2, 3, 4, 5])
.map(sum)
.value();
Or even simpler, like in the first answer
console.log(_.map(_.zip([0, 1, 2, 3, 4], [1, 2, 3, 4, 5]), sum));
Using underscore, #thefortheye's solution works well, here's a similar solution just using lazy.js instead;
> var Lazy = require('lazy.js');
> var addParts = function(x) { return Lazy(x).sum(); }
> Lazy([0,1,2,3,4]).zip([1,2,3,4,5]).map(addParts).toArray()
[ 1, 3, 5, 7, 9 ]
The above example can be achieved in the following way using underscore:
_.map([0, 1, 2, 3, 4], function(n, i) {
return n + i + 1
}) // This returns [1, 3, 5, 7, 9]
Here's a link to the API docs: Underscore#map

Are array views possible?

I would like to know if it's possible to mimic the constrained boundaries behaviour of an ArrayBufferView over an ArrayBuffer in a cross-browser compatible way (down to say IE8).
Consider a Javascript array structure like this:
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
I would like to obtain an array view b of a subset of a. Such as when an index of b is mutated, so is an index in a.
Usage example:
var b = ViewOf(a, 3, 6); // Make a view of a, from index 3 to 6
console.log(b); // [3, 4, 5, 6]
b[0] = 42;
console.log(a); // [0, 1, 2, 42, 4, 5, 6, 7, 8, 9]
i don't know about IE8, since it's Object.defineProperty is janky, but this seems to do what you ask, even if what you ask isn't the best idea ever for reasons pointed out in other comments:
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function ViewOf(orig, from, to){
var sub=orig.slice(from, to);
for(var i=0, mx=sub.length;i<mx;i++){(function(i){ var it=sub[i];
Object.defineProperty(sub, i, { get: function(){ return it;}, set: function(v){ return it=orig[i+from]=v; } });
}(i));}
return sub;
}
var b = ViewOf(a, 3, 6); // Make a view of a, from index 3 to 6
console.log(b); // [3, 4, 5, 6]
b[0] = 42;
console.log(a); //shows: [0, 1, 2, 42, 4, 5, 6, 7, 8, 9]
That's not possible by default. you can mimic it with a custom function.
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
ViewOf = function(a, startIdxx, endIdxx){
return {
startIdx: startIdxx,
endIdx: endIdxx,
set: function(index, value){
a[index+this.startIdx] = value;
},
get: function(index){
return a[index+this.startIdx];
}
}
}
Now you can use the above function like below
b = ViewOf(a, 3, 6);
b.set(0, 42);
console.log(a);
JS Fiddle: http://jsfiddle.net/YewC4/4/
Have a look at https://github.com/inexorabletash/polyfill.
This polyfill lib has typedarray.js which contains polyfills for ArrayBuffer and ArrayBufferView.
I do not know this lib. Only a quick googleing..

Categories