webForumDet fria alternativet

keys i en array

6 svar · 570 visningar · startad av learn

learnMedlem sedan jan. 20051 130 inlägg
#1

Jag behöver få ut alla keys i en array.

Hittade denna:

function array_keys( input, search_value, strict ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} );
    // *     returns 1: {0: 'firstname', 1: 'surname'}
    
    var tmp_arr = {}, strict = !!strict, include = true, cnt = 0;
    
    for ( key in input ){
        include = true;
        if ( search_value != undefined ) {
            if( strict && input[key] !== search_value ){
                include = false;
            } else if( input[key] != search_value ){
                include = false;
            }
        }
        
        if( include ) {
            tmp_arr[cnt] = key;
            cnt++;
        }
    }
    
    return tmp_arr;
}

Det funkar bra i Firefox men blir katastrof i Internet Explorer.

I IE får jag ut följande keys: lastIndexOf, indexOf, toJSON

Vilket inte stämmer ett dugg...!

Så, hur kan man göra för att få ut array keys i samtliga browsers.

stattinMedlem sedan jan. 2005713 inlägg
#2

Kan det här vara till hjälp? http://www.webforum.nu/showthread.php?p=856744#post856744

learnMedlem sedan jan. 20051 130 inlägg
#3

Nej, inte direkt.

Detta är den kod jag försöker köra:

<script type="text/javascript">

function arr_keys(arr)
{
	var tmp_arr = new Array(arr.length);
	var i = 0;
 
	for (key in arr)
    {
    	tmp_arr[i] = key;
		i++;
		
		if (i == arr.length) { break; }
    }

	return tmp_arr;
}

var enarray = Array(3);

enarray["kalle"] = "fotboll";
enarray["per"] = "bandy";
enarray["olle"] = "fotboll";

var keys = Array(3);

keys = arr_keys(enarray);

for (i=0; i<keys.length; i++)
{
	alert(keys[i]);
}

</script>

I Firefox funkar det bra. Då får jag meddelandena "kalle", "per" och "olle". I Internet Explorer däremot får jag "lastIndexOf", "indexOf" och "toJSON".

Helsjukt!

Någon som vet varför och hur jag ska göra istället?? :q

R: Funkar finfint i Google Chrome också... j-a IE!

jmeMedlem sedan maj 20012 237 inlägg
#4

http://blog.xkoder.com/2008/07/10/javascript-associative-arrays-demystified/

Testa detta:

for(key in enarray)
{
alert(key + ": " + enarray[key]);
}

nitro2k01Medlem sedan aug. 20039 342 inlägg
#5

Jag såg att stattin har länkat till mitt 4 år gamla inlägg. Dock behöver det inlägget revideras lite.

Objekt och arrayer är två (delvis) olika saker i Javscript. Ett objekt är samma sak som en haslista, eller med andra ord en lista där index kan bestå av strängar. Det finns två syntaxer för att komma åt egenskaper för ett objekt: objektet.egenskapen och objektet["egenskapen"]
Båda är funktionellt ekvivalenta förutom att nr 1 är begränsat till att namnet för egenskapen är begränsat till tecken som får användas i variabelnamn, och du kan passa valfri sträng till nr 2. (Detta kan vara intressant om du behöver konstruera en sträng och använda som index.) Men på alla ställen där du kan använda nr 1 kan du använda nr 2 istället.
T ex går det utmärkt att skriva document["getElementById"]("någotID"); istället för document.getElementById("någotID");

En array däremot är ett specialfall av ett objekt. En array, som har klassen Array, är en subklass av klassen Object. Allt som gäller för Object gäller således för Array. Att, som jag skrev i mitt gamla inlägg, arrayer kan ha strängindex är alltså egentligen inget annat än en konsekvens av att objekt i allmänhet kan ha det.
Arrayer har alltså alla egenskaper som objekt har, och ett par till som t ex egenskapen length som reflekterar arrayens längd och metoden sort som kan användas för att sortera elementen i arrayen.

Vad gör då for(i in array)? Jo, den går igenom all index som objektet array har. for(i in x) opererar alltså på objekt, och även på arrayer som alltså råkar vara ett specialfall av objekt. Normalt ska en array bara innehålla de numeriskt indexerade elementen. Och om man lägger till fler element, även dessa.

Hur förklarar det att "lastIndexOf", "indexOf", "toJSON" dyker upp? Jo, dessa är metoder som man kan använda för att plocka element, samt konvertera till JSON-format, respektive. Microsoft verkar dock ha lagt till dessa element med ett fulhack som gör att de listas i for(i in x) som objekt-egenskaper. Detta är helt enkelt en bugg i IE. (Eller eventuellt ett resultat av något JS-ramverk du använder, som prototype eller jQuery. Jag har itne IE7 installerat så jag kan inte kolla hur det funkar)

Lösningen är att definiera enarray som objekt istället för som array. (Ty du använder den som ett objekt) En sak du kan tänka på är att du normalt inte behöver ange storleken när du skapar en array. I arr_keys är det onödigt, men oskadligt. I deklarationen av enarray är det direkt felaktigt. Längden 3 gör att enarray[0], enarray[1] och enarray[2] reserveras och enarray.length sätts till 3, men har ingen effekt alls på kalle, per och caroline.

Jag föreslår följande kod. Notera hur jag demonstrativt har bytt ut arr mot obj där det är relevant. Notera också hur jag använder array-metoden push för att dynamiskt lägga till element sist i arrayen.

<script type="text/javascript">
function obj_keys(arr)
{
	var tmp_arr = [];	// [] är ekivalent med new Array();

	for (key in arr)
		tmp_arr.push(key);

	return tmp_arr;
}

var ettobjekt = {};	// {} är ekivalent med new Object();

ettobjekt["kalle"] = "fotboll";
ettobjekt["per"] = "bandy";
ettobjekt["caroline"] = "fotboll";

var keys = obj_keys(ettobjekt);

for (i=0; i<keys.length; i++)
{
	alert(keys[i]);
}
</script>

Må detta inlägg vara i fyra år till innan det behöver revideras. ;)

colioneMedlem sedan juni 20014 421 inlägg
#6

Om ett ramverk används finns det tyvärr en möjlighet att man även har protypat på indexOf, lastIndexOf och toJSON på object. Men iom att det ligger i prototypen så kan man använda hasOwnProperty för att endast plocka sådant som ligger direkt på objektet och inte i prototyp-kedjan.

Jämför resultaten i de två olika looparna:

<script type="text/javascript">
  Object.prototype.fest = function() {
    return true;
  }

function obj_keys(arr)
{
  var tmp_arr = [];	// [] är ekivalent med new Array();

  for (key in arr) {
    if (arr.hasOwnProperty(key)) { //fest är inte ett property som ligger direkt på enarray, utan i prototypen på objekt. Därför freturnar den false på hasOwnProperty.
      tmp_arr.push(key)
    }
  }

  return tmp_arr;
}

function obj_keys_w_proto(arr)
{
  var tmp_arr = [];	// [] är ekivalent med new Array();

  for (key in arr) 
      tmp_arr.push(key)
  

  return tmp_arr;
}

var ettobjekt = {};	// {} är ekivalent med new Object();

ettobjekt["kalle"] = "fotboll";
ettobjekt["per"] = "bandy";
ettobjekt["caroline"] = "fotboll";

var keys = obj_keys(ettobjekt);
alert("alla självägda egenskaper:")
for (i=0; i<keys.length; i++)
{
  alert(keys[i]);
}

var allkeys = obj_keys_w_proto(ettobjekt);
alert("alla självägda plus prototyp:")
for (i=0; i<allkeys.length; i++)
{
  alert(allkeys[i]);
}
</script>
learnMedlem sedan jan. 20051 130 inlägg
#7

nitro2k01, tack!!

colione, det funkar, tack ändå!

137 ms totalt · 3 externa anrop · v20260731065814-full.30151723
125 ms — hämta forumlista (db)
0 ms — hämta statistik (cache)
134 ms — hämta tråd, inlägg och bilagor (db)