ugrás a tartalomhoz

Nagyon szigorúan egyenlő… (JavaScript feladvány)

presidento · 2010. Aug. 5. (Cs), 08.33

…avagy vannak egyenlők, és vannak egyenlőbbek.

Az ECMAScript 5 szabványt olvasgatva találtam rá, hogy a JavaScriptben két változó lehet:

  1. különböző (a != b, ez a does-not-euals operator)
  2. egyenlő (a == b, ez az equals operator)
  3. szigorúan egyenlő (a === b, ez a strict equals operator)
  4. nagyon szigorúan egyenlő (a ==== b, nincs ilyen operátor)

Ez utóbbi legyen olyan, hogy ha a !== b, akkor a !=== b is, és ha a ==== b, akkor a === b is, és reméljük, hogy tudunk szigorítani az egyenlőségen.

A feladat a következő: kéretik kitalálni olyan „f” egy változós, visszatérési értékében csak a bemenettől függő függvényt, azaz

a ==== b; // esetén (ha lenne ilyen operátor)
f(a) == f(b);

Valamint olyan a és b változókat melyre

a === b; // de
f(a) != f(b);

Azaz a és b szigorúan egyenlő, azonban megkülönböztethető értékű változók.

(A megfejtést jövő hétfőig várom hozzászólásban.)

 
1

a === b, f(a) != f(b)

T.G · 2010. Aug. 5. (Cs), 09.56
Szerintem:

var a = b = Object;
function f (type) {
    return new type;
}

console.log(a === b, f(a) != f(b));
8

Nem jó a függvény

presidento · 2010. Aug. 5. (Cs), 12.41
A feladat az volt, hogy a ==== b esetén f(a) == f(b) (ezt nem teljesíti a tiéd), és kell mutatni olyan esetet, amikor a === b, de a !=== b, így f(a) != f(b).
2

ez milyen?

dyuri · 2010. Aug. 5. (Cs), 10.05

function ezmiez() { return Math.random(); }
function f(x) { try { return x(); } catch(e) { return x; } }
a = ezmiez;
b = ezmiez;
a === b; // true
f(5) == f(5); // ezis true
f(a) != f(b); // es valoban nem egyenloek
4

Igazából a Math.random()-ot

Török Gábor · 2010. Aug. 5. (Cs), 10.52
Igazából a Math.random()-ot felesleges is függvénybe burkolni.
var a = b = Math.random;
9

Nem jó a függvény.

presidento · 2010. Aug. 5. (Cs), 12.43
Nem olvastad el figyelmesen, mit kell tudnia a függvénynek: http://weblabor.hu/blog/20100805/nagyon-szigoruan-egyenlo#comment-70005
12

miert is nem?

dyuri · 2010. Aug. 5. (Cs), 13.31
hat amig azt nem mondtad, hogy az 'a = b'-bol kovetkezik az 'a ==== b' (nekem ez annyira nagyon nem kovetkezik abbol amit leirtal), addig szerintem minden feltelet teljesitett
17

Ennyit mondtál el: (a====b :

inf3rno · 2010. Aug. 5. (Cs), 16.50
Ennyit mondtál el:
(a====b : a===b && f(a)==f(b)) + (f(a)==f(b) !: a===b)

(A ":" azt jelenti, hogy következik valami valamiből, a "+" pedig az és-nek felel meg.)

Szavakkal: ha "a" szigorúan egyenlő "b"-vel, akkor abból következik, hogy "a" típusa és értéke egyenlő lesz "b" típusával és értékével, és "f(a)" értéke egyenlő lesz "f(b)" értékével, de abból, hogy "f(a)" értéke egyenlő "f(b)" értékével nem következik, hogy "a" típusa és értéke egyenlő "b" típusával és értékével.

Úgy általánosságban bármi olyan megfelel, ami kiválaszt egy típust vagy értéket, és arra mindig olyan eredményt ad, ami az equals-nak megfelel, a többire meg olyan értéket, ami a not equals-nak felel meg. Még csak azt sem szabtad meg, hogy f(a)==f(a) legyen.

pl ez is tökéletesen megfelel:

function vseq(a,b)
{
	var f=function (x)
	{
		return (
			(typeof(x)=="number")
			?true
			:{}
		);
	};
	return a===b && f(a)==f(b);
}

function test(a,b)
{
	return "\n a===b: "+(a===b?"true":"false")+"\n a====b: "+(vseq(a,b)?"true":"false");
}


alert("a és b nagyon szigorúan egyenlőek"+test(1,1));
alert("a és b szigorúan egyenlőek, de nem nagyon szigorúan egyenlőek"+test("a","a"));
alert("a és b nem egyenlőek"+test(1,2));

Összefoglalva: gyakorlatilag bármit írhatsz az "a====b: a===b && " után, ami neked tetszik. Szóval az egésznek szerintem semmi értelme, annyi, hogy az "a szigorúan egyenlő b"-hez hozzávettél még egy feltételt, aztán azt tovább bonyolítottad, hogy függvénybe zárva legyen.
Hajtasz a tárhelyre? :D
18

sorry

presidento · 2010. Aug. 5. (Cs), 19.33
Reméltem, hogy azért mindenki úgy gondolja, hogy akármilyen nagy szigorúsággal nézzük, egy (nem NaN) érték önmagával egyenlő. (És akkor a legszigorúbb értelemben is a ==== a, ami miatt f(a) == f(a).

http://weblabor.hu/blog/20100805/nagyon-szigoruan-egyenlo#comment-70042
22

Reméltem, hogy azért mindenki

inf3rno · 2010. Aug. 5. (Cs), 20.47
Reméltem, hogy azért mindenki úgy gondolja, hogy akármilyen nagy szigorúsággal nézzük, egy (nem NaN) érték önmagával egyenlő.


Ez a feladat leírásából nem következett. Csak azt kaptad, amit kértél, nem többet vagy kevesebbet.

Továbbra sem hiszem, hogy ennek az egésznek bármi értelme lenne, majd elolvasom a megoldást, abból talán kiderül, hogy mit akartál.
23

szerintem meg igy is sikerult

Tyrael · 2010. Aug. 5. (Cs), 22.00
szerintem meg igy is sikerult erhetobben megfogalmaznia a mondanivalojat, mint neked a multkori singletonos blogpostodban, ott megsem kezdett el szemelyeskedni veled senki. :)

Tyrael
25

Hát bocs, ha

inf3rno · 2010. Aug. 6. (P), 02.42
Hát bocs, ha személyeskedésnek hangzik. :-)
Nem értem, hogy mi a cél, de majd úgyis kiderül. :-)

Ugye:
a==b -> a és b értéke egyenlő
a===b -> a==b && a és b típusa egyenlő
a====b -> a===b && f(a)==f(b)


Az uccsónak max úgy lenne értelme, ha azt vizsgálnánk, hogy a két pointer ugyanarra a memória címre mutat e, vagy sem. Az objecteknél így hasonlít össze a szigorúan egyenlő (1-2 bugtól eltekintve), a sima változóknál viszont érték és típus szerint, és tudtommal nem lehet lekérni, hogy hova mutat a pointer, szóval azt sem, hogy nagyon szigorúan egyenlő e két változó.

A sima változókhoz tartozó objektumokkal sem lehet mit kezdeni, mert minden lekérésnél új példány jön létre:

Object.prototype.f=function ()
{
	return this;
};

var a=1;
alert(a.f()===a.f());
Innentől kezdve esélytelen.

Egyébként ha szimplán a logikát nézzük, akkor meg hiányzik az, hogy "f(a)==f(a)" minden "a" esetén a feltételek listájából, különben az én megoldásom jó lenne. (Mondjuk http://weblabor.hu/blog/20100805/nagyon-szigoruan-egyenlo#comment-70042 -ben már javította ezt a hiányosságot.)
3

en ugy ertelmeztem a

Tyrael · 2010. Aug. 5. (Cs), 10.36
en ugy ertelmeztem a feladatot, hogy az eddig szuletett ket megoldas nem elegendo.
a randomos megoldas megserti azt a feltetelt, hogy csak a bemenettol fugg a kimenet.
a new type-os mar szintaktikailag megoldas, de szerintem a kerdezo valami sokkal trukkosebb megoldast talalt, mint az, hogy 2 object csak akkor szigoruan egyenlo ha ugyanarra a peldanyra mutatnak.

Tyrael
6

ez a feltetel szerintem az

dyuri · 2010. Aug. 5. (Cs), 11.39
ez a feltetel szerintem az f-re vonatkozott

a new type-os peldaval kapcsolatban meg nem tudok olyan peldat mondani, ahol a ==== b, es f(a) == f(b), es nem csak azert nem, mert nem tudom pontosan mit nezne az ==== :)

egyebkent az eredeti felvetessel kapcsolatban, a ====-nak nem latom ertelmet
5

NaN

Török Gábor · 2010. Aug. 5. (Cs), 10.59
Bármilyen megfelelően választott argumentum esetén NaN-nal visszatérő függvény megteszi.

var a = b = "lol";

function f (x) {
  return parseInt(x);
}

a === b // true
f(a) != f(b) // true
NaN == NaN // false
7

Re: NaN

T.G · 2010. Aug. 5. (Cs), 11.49
Ebben a megoldásban még az a szép, hogy igazából egy sorra is redukálható:
var a = b = f = parseInt;
10

Nem jó a függvény

presidento · 2010. Aug. 5. (Cs), 12.46
Nem olvastad el figyelmesen, mit kell tudnia a függvénynek: http://weblabor.hu/blog/20100805/nagyon-szigoruan-egyenlo#comment-70005
a ==== b // ellenben
f(a) != f(b) 
13

A feladat az volt, hogy a

Török Gábor · 2010. Aug. 5. (Cs), 14.06
A feladat az volt, hogy a ==== b esetén f(a) == f(b)
var a = b = 1,
    f = parseInt;
a ==== b // true
f(a) == f(b) // true (1)
és kell mutatni olyan esetet, amikor a === b, de a !=== b, így f(a) != f(b)
var a = b = f = parseInt;
a === b //true
f(a) != f(b) // true (NaN)
Vagy félreértelek.
14

igen, enis igy gondoltam, de

dyuri · 2010. Aug. 5. (Cs), 14.15
igen, enis igy gondoltam, de itt alattunk irja, hogy 'a = b' -> 'a ==== b' (ami nekem nem kovetkezik), es akkor a masodik resz nemjo
15

Igaz.

Török Gábor · 2010. Aug. 5. (Cs), 14.26
Igaz.
19

sorry

presidento · 2010. Aug. 5. (Cs), 19.35
Bocsi, reméltem, hogy azért mindenki úgy gondolja, hogy akármilyen nagy szigorúsággal nézve is, de egy (nem NaN) érték önmagával egyenlő…

http://weblabor.hu/blog/20100805/nagyon-szigoruan-egyenlo#comment-70042
11

Kihagytam valamit…

presidento · 2010. Aug. 5. (Cs), 12.50
…ami impliciten azért benne volt.

A ==== operátor egy még szigorúbb értelemben vett egyenlőséget akar jelenteni, így a feltételekhez illett volna hozzávenni, hogy azonosság esetén, vagyis például az a = b művelet után a ==== b lesz természetesen.
16

Re: implicit :)

T.G · 2010. Aug. 5. (Cs), 14.46
Ez szerintem nem magától értetődő. :)
A NaN példa nekem tetszett, ezért azt folytatva:

var a = NaN;
var b = a;
a == b; // false;
Tehát még a két egyenlőség jel sem teljesül, nemhogy a négy. :)
20

igazad van

presidento · 2010. Aug. 5. (Cs), 19.36
A NaN kizárását meg akartam említeni, de olyan váratlanul ért a fenti vita, hogy egy rövid munkahelyi szünetben írtam a fenti példát, és a sietség miatt lemaradt. De lásd az alábbi hozzászólásomat, ott igyekszem érthetőbben kifejteni a feladatot.
21

Másképpen megfogalmazva a feladatot

presidento · 2010. Aug. 5. (Cs), 20.06
Nem akartam senkit sem megsérteni a túlságos bőbeszédűséggel, a fenti vita szerint nem sikerült megtalálni az egyensúlyt.

Megpróbálom megfogalmazni másképpen.

Nyilvánvaló, hogy ha „a” és „b” változók (gyengén) egyenlőek, abból nem következik, hogy szigorúan egyenlőek. (Azaz a == b =X=> a === b)
Azt állítom, hogy ha „a” és „b” változók szigorúan egyenlőek, abból nem következik, hogy azonosak (nagyon szigorúan egyenlőek, pontosan megegyeznek, stb.). (Azaz a === b =X=> a ==== b)

Mivel a Javascriptben nincsen azonosságot vizsgáló operátor (====), ezért az állítás bizonyítása egy módon lehetséges: ha találunk olyan „a” és „b” változót, hogy a === b ellenére meg tudjuk különböztetni őket. Hogyan lehet megkülönböztetni? Kell egy olyan egy változós, csak a bemenetétől függő függvényt* mutatnunk, amely „a”-ra és „b”-re különböző eredményt ad.

* „csak a bemenetétől függ”: ez alatt azt értem, hogy ha var x = f(a);, akkor x == f(a); minden esetben. (Kérlek, akard megérteni! Hadd ne kelljen belemenni, hogy csak az „x” definíciója után, a scope-on belül, abban az esetben, ha sem „x”, sem „f”, sem „a” értéke nem változik, stb.)

Tehát: keresünk olyan „a”, és vele nem azonos, de szigorúan egyenlő „b” változót és olyan a fenti kritériumokat teljesítő „megkülönböztető” „f” függvényt, melyre
//minden
x ==== y; // esetén (ha „x” azonos „y”-vel)
f(x) == f(y);

// viszont a fenti két változóra
a === b; // de
f(a) != f(b);
(Mit értek azonos – szigorúan egyenlő, pontosan megegyező, stb. – alatt? Nyilvánvalóan egy nem NaN érték azonos önmagával. Ha két változó azonos, akkor szigorúan is egyenlő. Ha két változó nem szigorúan egyenlő, akkor nem is azonos.)

A lényeg: az egyik kezemben van „a”, a másikban „b”, és a === b. Te mégis pontosan meg tudod mondani, melyik kezemben melyik van. Hogyan lehetséges ez? Mi ez az „a” és „b”, és milyen módszerrel tudod őket megkülönböztetni?
24

Azonosságot létrehozó operátor?

zzrek · 2010. Aug. 6. (P), 00.58
Írtad, hogy "... a Javascriptben nincsen azonosságot vizsgáló operátor..." de mégis szeretnéd ezt megállapítani, annak az az alapfeltétele, hogy egyáltalán legyen "azonosságot létrehozó" operátor. Van ilyen? Mondjuk a sima értékadás az ilyen?

a=5;
b=a;
c=4+1;
d=5;
Ebben az esetben a====5 és b====a de c!====a és b!====5 és bár d-re (hasonlóan mint a-ra) is igaz, hogy d====5, de mégis d!====a

Valami ilyesmire gondolsz?
Ebben az esetben az azonosságot vizsgáló operátor valamilyen "közvetlen származtatást" vizsgáló operátor lehetne. (Valahogy sérülne valamilyen következetességi szabály, hiszen erre az operátorra nem lenne érvényes a következtetés, hogy ha a====b és b====c akkor a====c)
26

Így, ahogy írod

presidento · 2010. Aug. 6. (P), 06.53
A sima értékadás (a NaN kivételével) tudtommal azonosságot hoz létre.

Jelen példában a ==== b ==== c ==== d, mert az „5” mindenhol ugyanaz az „5”, és a „4+1” eredményeként létrejövő „c” értékét sem tudod semmilyen módon megkülönböztetni például „b” értékétől.

Ha két érték minden körülmények között pontosan ugyanúgy viselkedik (azaz nem tudod megkülönböztetni őket), akkor azonosak. Olyan „a” és „b” kell, hogy meg lehet különböztetni őket (tehát nem azonosak) annak ellenére, hogy a === b
27

Én kezdem elveszteni a fonalat. :)

T.G · 2010. Aug. 6. (P), 09.43
Ha a var a = 4, b = 2 + 2; esetén a ==== b egyenlőség fennáll, akkor azt kijelenthetjük, hogy az összes skalár értéknél az a === b esetén következik az a ==== b. Nem?
Másik oldalról ha két "ugyanolyannak tűnő" objektum - amely másik memória címen van - esetén az a === b sosem áll fent, így az a ==== b sem. (hasonlóan két ugyanolyan függvény esetén sem lesz egyenlőség)
Ebben az esetben, akkor még mi marad, ha még a NaN-t is kizártuk?
28

Kezded megtalálni a fonalat! :)

presidento · 2010. Aug. 6. (P), 09.58
Jó irányban gondolkozol. :)

Az bizonyos, hogy az objektumokat kizárhatjuk a játékból, hiszen objektumok esetén a === b akkor lehet, ha „a” és „b” ugyanarra az objektumra hivatkozik.

Maradnak a primitív típusok.
29

Azonosságot vizsgáló operátor

zzrek · 2010. Aug. 6. (P), 11.22
Nos, akkor ezek szerint a te példád fogalmai szerint is elfogadod, hogy a sima értékadás azonosságot hoz létre, viszont állítod, hogy az "===" operátor nem megfelelő az azonosság vizsgálatára, mert találtál rá kivételt.

Valami ilyesmi jutott az eszembe:

a=[1,2,3,4,5];
b=1;
a[0]===b;
Ezek szerint a[0]!====b, ha jól értem.

De nem, valószínűleg nem erre gondolsz, már sejtem hogy mi lehet:

a=[[1],[2],[3]];
b=[a[0],a[1],a[2]];
a[0]===b[0];
De ebben az esetben a[0]!====b[0], ugye?
(Mivel nem ugyanabban az objektumban vannak, meg lehet különböztetni őket.)
31

Nem talált

presidento · 2010. Aug. 6. (P), 12.05
Ha nem azonos, akkor meg lehet különböztetni: mutass egy olyan f „megkülönböztető” függvényt, ami minden x-re f(x) == f(x), viszont az adott „a”-ra és „b”-re f(a) != f(b) annak ellenére, hogy a === b

A te esetedben a[0] és b[0] ugyanarra az „x” objektumra mutat, ezért valószínűleg nem fogsz tudni olyan (a feltételeknek megfelelő) függvényt találni, ami megkülönbözteti őket.
35

Pedig

zzrek · 2010. Aug. 6. (P), 12.56
Pedig ennek lenne gyakorlati haszna.
30

megoldás

bamegakapa · 2010. Aug. 6. (P), 12.01

var a=+0, b=-0;
var f=function (x){
    return 1/x;
}
console.log(a===b);
console.log(f(a)==f(b));
Amennyiben jól értelmeztem a feladatot :).
32

Pontosan

presidento · 2010. Aug. 6. (P), 12.20
Gratulálok, ott a pont!

A +0 és a -0 között egyetlen különbség van, ha ezzel osztunk egy nem nulla véges számot: 1/+0 == +Infinity, ellenben 1/-0 == -Infinity.

Minden más esetben pontosan ugyanúgy viselkednek, és -0 === +0.

Ha minden feltételnek meg akarunk felelni, akkor a függvényt úgy írhatnánk, hogy
return typeof x == 'number' ? 1/x : 0;
mert különben nem számokra NaN lenne, ami semmivel nem egyenlő, tehát sérül az f(x) == f(x) kitétel.

De ez csak apróság, jó a megoldásod, gratulálok még egyszer!
33

nos igen

bamegakapa · 2010. Aug. 6. (P), 12.37
Valóban úgy tökéletes, ahogy írod, hanyag módon amint rájöttem a dolog lényegére, azonnal beküldtem, nehogy valaki megelőzzön :).

Hátha nyerek egy IEEE 754 feliratú pólót vagy bögrét :).
37

Grat. :-)

inf3rno · 2010. Aug. 6. (P), 12.58
Grat. :-)
34

var x=-0; switch(x) { case

inf3rno · 2010. Aug. 6. (P), 12.37

var x=-0;
switch(x)
{
	case 0:
		alert("0");
		break;
	case -0:
		alert("-0");
}
Anno php-ben is megvolt ez a bug, amíg nem javíttattam...
38

Pedig

Ifju · 2010. Aug. 7. (Szo), 08.21
Pedig ha dokumentálják, akkor máris nem bug, hanem feature. :)
36

fenebe, pedig en is neztem a

Tyrael · 2010. Aug. 6. (P), 12.57
fenebe, pedig en is neztem a +- nullat, csak nem jottem ra, hogyan lehetne elerni benne ezt a kulonbseget. :(

Tyrael