i'm currently learning js and need to pass a test, every requirement checks out besides "should work on an arguments object".
So I need to use arguments[0]or[1], its also necessary for me to check if the array is an array. Issue here is that for some reason the Array.isArray() part of the code turns my "should work on an arguments object" requirement false, even though I used arguments[0].
please try to ignore the rest of the code, there are also other requirements set. I know they seem kind of unnecessary to include.
this is my code:
function (array, n) {
var resultArray = [];if (typeof arguments[1] !== "number" || arguments[1] == 0 || arguments[1] < 0){
resultArray.push.call(resultArray, arguments[0][0])
return resultArray
}
else if (arguments[1] > arguments[0].length){
return arguments[0] && array
} else {
return resultArray;
}
};
That's because the requirements expects you use somewhere the variable argument array. Instead you use arguments[0].
So use the first over the latter.
Likewise, use n instead of arguments[1]
You can use Array.prototype.slice function simply
const first = (array = [], n = 1) =>
Array.isArray(array) ? array.slice(0, array.length >= n ? n : 1) : [];
If n > array.length this will return the whole array.
Try this:
if (!window[atob('QXJyYXk=')][atob('aXNBcnJheQ==')](arguments[0])) return [];
I was working on a coding problem and I came across something that's throwing me for a loop(no pun intended). It's fairly simple, but I'm hoping for clarity from someone with more experience.
I was trying to solve it as such, but it wasn't working (I know it isn't necessary to check for zero, but I was just messing around and found this "quirk")
const filter_list = (l) => {
return l.filter(item => {
if(typeof item === 'number' || item === 0) {
return item;
}
})
}
It wasn't passing the tests, but when it's written like this, it passes all the tests:
const filter_list = (l) => l.filter(item => typeof item === 'number' || item === 0);
What is it about the second version that makes it pass the tests? There's a syntax difference, but the logic seems like it's the same to me.
The logic isn't the same. In the first version you have return item;, you don't return item in the second version. The second version returns the condition result.
The second version is equivalent to this:
const filter_list = (l) => {
return l.filter(item => {
return typeof item === 'number' || item === 0;
})
}
And if you want to abbreviate the first function, it would be:
const filter_list = (l) => l.filter(item => typeof item === 'number' || item === 0 ? item : undefined);
Your condition logic also doesn't make much sense. It will be true for all numbers, so adding || item === 0 won't change the result. I suspect you meant &&. But since you're using strict equality, there's no need to test the type -- nothing but a number can be strictly equal to 0.
What’s wrong with my search function? It works for the first line (city values), but not for the others.
If I remove everything but the cityValues line, or change the && to ||, the function works, but not like this.
I’m trying to search through an array of parameters on each value. Meaning: the user has the possibility to select multiple options from multiple dropdowns, and see the results.
For some context, cityValue, zipValue etc are arrays.
cityValue is an array of strings, and the rest are arrays of numbers.
Thanks
computed: {
filteredPropertyTypes() {
return this.propertyTypes.filter(rental => {
return this.cityValue.indexOf(rental.city) !== -1 &&
this.zipValue.toString().indexOf(rental.zip.toString()) !== -1 &&
this.bedroomsValue.toString().indexOf(rental.bedrooms.toString()) !== -1 &&
this.bathroomsValue.toString().indexOf(rental.bathrooms.toString()) !== -1 &&
rental.rent.toString().includes(this.rentValue.toString());
})
}
},
According to MDN, The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
arr.indexOf(searchElement[, fromIndex])
The indexOf() method works on Arrays and looking at your function, you are using strings as your array.
For more on the indexOf() method, check here
EDIT -- based on the additional information, if cityValue, zipValue etc are arrays originally, using the toString() method on them causes them to become strings
Try changing your code to
computed: {
filteredPropertyTypes() {
return this.propertyTypes.filter(rental => {
return this.cityValue.indexOf(rental.city.toString()) !== -1 &&
this.zipValue.indexOf(rental.zip) !== -1 &&
this.bedroomsValue.indexOf(rental.bedrooms) !== -1 && this.bathroomsValue.indexOf(rental.bathrooms) !== -1 && rental.rent.includes(this.rentValue);
})
}
},
I need to check if any object in an array of objects has a type: a AND if another has a type: b
I initially did this:
const myObjects = objs.filter(attr => attr.type === 'a' || attr.type === 'b');
But the code review complained that filter will keep going through the entire array, when we just need to know if any single object meets either criteria.
I wanted to use array.find() but this only works for a single condition.
Is there anyway to do this without using a for loop?
you can pass two condition as given below
[7,5,11,6,3,19].find(attr => {
return (attr > 100 || attr %2===0);
});
6
[7,5,102,6,3,19].find(attr => {
return (attr > 100 || attr %2===0);
});
102
Updated answer:
It's not possible to shortcircuit js's builtin functions that does what you want, so you will have to use some kind of loop:
let a;
let b;
for (const elm of objs) {
if (!a && elm === 'a') {
a = elm;
}
if (!b && elm === 'b') {
b = elm;
}
const done = a && b;
if (done) break;
}
Also you should consider if you can record a and b when producing the array if that's possible.
Oiginal answer:
`find` works just like `filter` where it takes a predicate, returns the first element that the predicate returns `true`.
If I understood your question correctly, you can just replace the `filter` with `find` and it will return at the first occurance:
const myObject = objs.find(attr => attr.type === 'a' || attr.type === 'b');
Also notice your provided snippet is wrong for what you described: `filter` returns an array but you only wanted one element. so you should add `[0]` to the filter expression if you want to use it.
Update 2
I added a weight lookup to the sort function, which increased the performance by about 100% as well as the stability, as the previous sort function didn't consider all types, and as 1 == "1" the result depends on the initial order of the Array, as #Esailija points out.
The intent of the question is to improve this Answer of mine, I liked the question and since it got accepted and I felt like there is some performance to squeeze out of the sort function. I asked this question here since I hadn't many clues left where to start.
Maybe this makes things clearer as well
Update
I rephrased the complete question, as many people stated I was not specific enough, I did my best to specify what I mean. Also, I rewrote the sort function to better express the intent of the question.
Let arrayPrev be an Array (A) ,where A consists of 0 to n Elements' (E)
Let an Element either be
of a Primitive type
boolean, string, number, undefined, null
a Reference to an Object O, where O.type = [object Object] and O can consist of
0 to n Properties P, where P is defined like Element plus
an circular Reference to any P in O
Where any O can be contained 1 to n times. In the sense of GetReferencedName(E1) === GetReferencedName(E2)...
a Reference to an O, where O.type = [object Array] and O is defined like A
a circular Reference to any E in A
Let arrayCurr be an Array of the same length as arrayPrev
Illustrated in the following example
var x = {
a:"A Property",
x:"24th Property",
obj: {
a: "A Property"
},
prim : 1,
}
x.obj.circ = x;
var y = {
a:"A Property",
x:"24th Property",
obj: {
a: "A Property"
},
prim : 1,
}
y.obj.circ = y;
var z = {};
var a = [x,x,x,null,undefined,1,y,"2",x,z]
var b = [z,x,x,y,undefined,1,null,"2",x,x]
console.log (sort(a),sort(b,a))
The Question is, how can I efficiently sort an Array B, such that any Reference to an Object or value of a Primitive, shares the exact same Position as in a Previously, by the same compareFunction, sorted, Array A.
Like the above example
Where the resulting array shall fall under the rules.
Let arrayPrev contain the Elements' of a and arrayCurr contain the Elements' of b
Let arrayPrev be sorted by a CompareFunction C.
Let arrayCurr be sorted by the same C.
Let the result of sorting arrayCur be such, that when accessing an E in arrayCur at Position n, let n e.g be 5
if type of E is Object GetReferencedName(arrayCurr[n]) === GetReferencedName(arrayPrev[n])
if type of E is Primitive GetValue(arrayCurr[n]) === GetValue(arrayPrev[n])
i.e b[n] === a[n] e.g b[5] === a[5]
Meaning all Elements should be grouped by type, and in this sorted by value.
Where any call to a Function F in C shall be at least implemented before ES5, such that compatibility is given without the need of any shim.
My current approach is to Mark the Objects in arrayPrev to sort them accordingly in arrayCurr and later delete the Marker again. But that seems rather not that efficient.
Heres the current sort function used.
function sort3 (curr,prev) {
var weight = {
"[object Undefined]":6,
"[object Object]":5,
"[object Null]":4,
"[object String]":3,
"[object Number]":2,
"[object Boolean]":1
}
if (prev) { //mark the objects
for (var i = prev.length,j,t;i>0;i--) {
t = typeof (j = prev[i]);
if (j != null && t === "object") {
j._pos = i;
} else if (t !== "object" && t != "undefined" ) break;
}
}
curr.sort (sorter);
if (prev) {
for (var k = prev.length,l,t;k>0;k--) {
t = typeof (l = prev[k]);
if (t === "object" && l != null) {
delete l._pos;
} else if (t !== "object" && t != "undefined" ) break;
}
}
return curr;
function sorter (a,b) {
var tStr = Object.prototype.toString
var types = [tStr.call(a),tStr.call(b)]
var ret = [0,0];
if (types[0] === types[1] && types[0] === "[object Object]") {
if (prev) return a._pos - b._pos
else {
return a === b ? 0 : 1;
}
} else if (types [0] !== types [1]){
return weight[types[0]] - weight[types[1]]
}
return a>b?1:a<b?-1:0;
}
}
Heres a Fiddle as well as a JSPerf (feel free to add your snippet)
And the old Fiddle
If you know the arrays contain the same elements (with the same number of repetitions, possibly in a different order), then you can just copy the old array into the new one, like so:
function strangeSort(curr, prev) {
curr.length = 0; // delete the contents of curr
curr.push.apply(curr, prev); // append the contents of prev to curr
}
If you don't know the arrays contain the same elements, it doesn't make sense to do what you're asking.
Judging by the thing you linked, it's likely that you're trying to determine whether the arrays contain the same elements. In that case, the question you're asking isn't the question you mean to ask, and a sort-based approach may not be what you want at all. Instead, I recommend a count-based algorithm.
Compare the lengths of the arrays. If they're different, the arrays do not contain the same elements; return false. If the lengths are equal, continue.
Iterate through the first array and associate each element with a count of how many times you've seen it. Now that ES6 Maps exist, a Map is probably the best way to track the counts. If you don't use a Map, it may be necessary or convenient to maintain counts for items of different data types differently. (If you maintain counts for objects by giving them a new property, delete the new properties before you return.)
Iterate through the second array. For each element,
If no count is recorded for the element, return false.
If the count for the element is positive, decrease it by 1.
If the count for the element is 0, the element appears more times in the second array than in the first. Return false.
Return true.
If step 4 is reached, every item appears at least as many times in the first array as it does in the second. Otherwise, it would have been detected in step 3.1 or 3.3. If any item appeared more times in the first array than in the second, the first array would be bigger, and the algorithm would have returned in step 1. Thus, the arrays must contain the same elements with the same number of repetitions.
from the description, it appears you can simply use a sort function:
function sortOb(a,b){a=JSON.stringify(a);b=JSON.stringify(b); return a===b?0:(a>b?1:-1);}
var x = {a:1};
var y = {a:2};
var a = [1,x,2,3,y,4,x]
var b = [1,y,3,4,x,x,2]
a.sort(sortOb);
b.sort(sortOb);
console.log (a,b);
Your function always returns a copy of sort.el, but you can have that easier:
var sort = (function () {
var tmp;
function sorter(a, b) {
var types = [typeof a, typeof b];
if (types[0] === "object" && types[1] === "object") {
return tmp.indexOf(a) - tmp.indexOf(b); // sort by position in original
}
if (types[0] == "object") {
return 1;
}
if (types[1] == "object") {
return -1;
}
return a > b ? 1 : a < b ? -1 : 0;
}
return function (el) {
if (tmp) {
for (var i = 0; i < el.length; i++) {
el[i] = tmp[i]; // edit el in-place, same order as tmp
}
return el;
}
tmp = [].slice.call(el); // copy original
return tmp = el.sort(sorter); // cache result
};
})();
Note that I replaced sort.el by tmp and a closure. Fiddle: http://jsfiddle.net/VLSKK/
Edit: This (as well as your original solution)
only works when the arrays contain the same elements.
maintains the order of different objects in a
but
does not mess up when called more than twice
Try this
function ComplexSort (a, b)
{
if(typeof a == "object") {
a = a.a;
}
if(typeof b == "object") {
b = b.a;
}
return a-b;
}
var x = {a:1};
var y = {a:2};
var a = [1,x,2,3,y,4,x]
var b = [1,y,3,4,x,x,2]
a.sort(ComplexSort);
b.sort(ComplexSort);
console.log ("Consistent", a,b);