Solved

How do i get indexes of an array

Posted on 2011-09-14
20
504 Views
Last Modified: 2012-05-12
I have an array of zip-codes, where a company has been doing some jobs. In several cases they have been several times in the sam zip-area, so the same zip-code exist several times in the array like 85921 in the array below.
90210
85921
74851
55997
43390
85921
98643
75930
74981
75432
86388
85921
74989
43390

The question is how to register that some zip-codes exist more than one time in the array.

I was thinking something in the line of:
If (array[i]>=1){
  something
}
else{
something else
}

Open in new window

0
Comment
Question by:petersego
  • 7
  • 7
  • 5
  • +1
20 Comments
 
LVL 4

Expert Comment

by:Somersault
ID: 36541500
Hey!

Try this:
arr = ['90210',
'85921',
'74851',
'55997',
'43390',
'85921',
'98643',
'75930',
'74981',
'75432',
'86388',
'85921',
'74989',
'43390',
'85921'];

Array.prototype.howManyExistsOf = function(item){
	
	var arr = {};
	
	for(i=0; i<this.length; ++i) {
		if (this[i] == item) {
			if(!arr[item]) arr[item] = 1;
			else arr[item]++;
		}
	}
	
	if(!isNaN(arr[item])) return arr[item];
	
	return null;
};

trace(arr.howManyExistsOf("123"));

Open in new window


You use it like this(as seen in the code):
array.howManyExistsOf(string);

The prototype loops through the array and checks for the string, it returns a number if it finds it, otherwise it returns null.

Hope that helps!

Cheers,
Chris
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36543650
You can use an associative array for this kind of thing:

Let's call your original array originalList and the new array postalCodes:

var postalCodes:Object = {}; // this will hold unique postal codes
for each (var postalCode in originalList){
  postalCodes[postalCode]++;
}

trace(postalCodes[85921]); // returns 3

Open in new window


This works because the associative array can only have unique keys. If a key is not already defined (ie:L the first time we encounter that unique code), it gets auto-created. Then we add 1 to it (using ++ auto-increment operator). But, if the postal code already has been encountered and is already a key in the object, then we just increment it again (becomes 2, etc).

So now you have a list of unique postal codes and a way to find out how many times they've been accessed.
0
 

Author Comment

by:petersego
ID: 36544042
Thanks, that looks promising.
But trying to implement it, im getting a problem.
First of all: The original list comes from xml - see snippet 2.

function LoadXML(event:Event):void
{
	myXML = XML(myxmlLoader.data);
	var postList=myXML.zipcodes;
	for (i = 0; i < postList.zip.length(); i++){
		var zipcode=postList.zip[i].toString();
		var arr:Array = new Array(zipcode);
		var postalCodes:Object = {};
		for each (var postalCode in arr){
			postalCodes[postalCode]++;
			}
			trace(postalCodes[33200]);
	}
} 

Open in new window


 
<zipcodes>
      <zip>90210</zip>
      <zip>96290</zip>
	  <zip>26220</zip>
	  <zip>67240</zip>
	  <zip>86200</zip>
	  <zip>54200</zip>
	  <zip>57250</zip>
	  <zip>46290</zip>
	  <zip>33200</zip>
	  <zip>54200</zip>
	  <zip>98281</zip>
	  <zip>76220</zip>
	  <zip>94240</zip>
	  <zip>33200</zip>
	  <zip>85220</zip>
	  <zip>67280</zip>
	  <zip>33200</zip>
   </zipcodes>

Open in new window


My problem is that when I trace the result I get is this:
undefined
undefined
undefined
undefined
undefined
undefined
undefined
undefined
NaN
undefined
undefined
undefined
undefined
NaN
undefined
undefined
NaN

What is wrong here?
0
 
LVL 11

Expert Comment

by:petiex
ID: 36544457
The problem is that the value of the zipcode item of the array is undefined until you assign something to it, and, as undefined, it is not a number (NaN), hence cannot be incremented with ++.
function LoadXML(event:Event):void {
        myXML = XML(myxmlLoader.data);
        var postalCodes:Array = [];
        for each(var zipcode:String in myXML.zip) {
            if (isNaN(postalCodes[zipcode])) {
                postalCodes[zipcode] = 1;
            } else {
                postalCodes[zipcode]++;
            }
            trace(postalCodes[33200]);
        }
    }

Open in new window

0
 

Author Comment

by:petersego
ID: 36545007
You maybe right, but the solution from tomaugerdotcom, suggested that the trace-result should result in a number - not an indexation.

Beside: Shouldnt it be undefined - not NaN, that should be 1, while NaN should be incremented.
I dont know if the below is possible, but something like this:

if (undefined(postalCodes[zipcode])) {
                postalCodes[zipcode] = 1;
            } else {
                postalCodes[zipcode]++;
            }
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36550044
@petiex Did I screw that up? Maybe the old Perl autovivification trick doesn't work in AS3. < blush >

I think you can also refactor that as
if (!postalCodes[zipcode]){ postalCodes[zipcode] = 1; } else { postalCodes[zipcode]++ }

Open in new window


0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36550073
Just thinking about it, I remember when doing XML based stuff, that sometimes the value you get from an XML node ends up not being a string but being an XML node object. Do a trace of your loop that creates the original ZIP codes array and make sure that you're pushing actual strings into the array, not XML node objects. I see that you're using toString. Do you need to do
postList.zip[i].value

Open in new window

 instead?
0
 

Author Comment

by:petersego
ID: 36550286
Thanks, but what I do not get is that the result seems to recognize the content of the array, but doesnt react to your solution the right way.

function LoadXML(event:Event):void
{
	myXML = XML(myxmlLoader.data);
	var postList=myXML.zipcodes.zip;
	for (i = 0; i < postList.length(); i++){
		var zipcode=postList[i].toString();
	var postalCodes:Object = {};
	var arr:Array = new Array(zipcode);
	  for each (var postalCode in arr){
		  if (!postalCodes[postalCode]){
			  postalCodes[postalCode] = 1;
			  }
		  else {
			  postalCodes[postalCode]++ 
			}
		 }
		 trace(postalCodes[33200]);
	}

Open in new window


results in this:

undefined
undefined
undefined
undefined
undefined
undefined
undefined
undefined
1
undefined
undefined
undefined
undefined
1
undefined
undefined
1

which indicates, that looping through the array, the zipcodes, that are the same, are recognized. The positions are the same as in the example above, but there is no incrementation...


0
 
LVL 14

Accepted Solution

by:
tomaugerdotcom earned 400 total points
ID: 36550340
Make sure you do my loop OUTSIDE the loop in which you build your zipcode array.

So:

myXML = XML(myxmlLoader.data);
    var arr:Array = [];
        var postList=myXML.zipcodes.zip;
        for (i = 0; i < postList.length(); i++){
                var zipcode=postList[i].toString();
        arr.push(zipcode);
}
        var postalCodes:Object = {};
          for each (var postalCode in arr){
                  if (!postalCodes[postalCode]){
                          postalCodes[postalCode] = 1;
                          }
                  else {
                          postalCodes[postalCode]++ 
                        }
                 }
                 
        }
trace(postalCodes[33200]);

Open in new window


Sorry for the crappy formatting!
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36550344
oops - is there an extra right brace there at the end. Why oh why can't you edit your comments in EE???
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 11

Assisted Solution

by:petiex
petiex earned 100 total points
ID: 36550417
The reason the values are not being incremented is because your code re-initializes the postalCodes object for each node in the XML. It should be initialized once before the for loop begins.

The code that I posted traces this:
undefined
undefined
undefined
undefined
undefined
undefined
undefined
undefined
1
1
1
1
1
2
2
2
3

Is that not what is needed?
0
 

Author Comment

by:petersego
ID: 36550654
Thanks, now it works correctly and results in the number of times a specific zip-code is represented in the array. In this case the number 3.
0
 

Author Closing Comment

by:petersego
ID: 36550671
Thanks both.
0
 
LVL 11

Expert Comment

by:petiex
ID: 36550761
I hate to bring this up, but if you have any East coast zip codes that start with 0, this does not seem to work.
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36550981
That would make sense, as at some point, ActionScript will treat that zip code like a numeric scalar variable and drop the leading zero. You have to make sure that the associative array's key is a string, not a numeric value, and that at no time do you treat the zip codes as numeric.

I wonder if a Dictionary would have the same problem?  http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Dictionary.html
0
 
LVL 11

Expert Comment

by:petiex
ID: 36551041
The weird thing is it doesn't even do that, because you can access, for example, the number of 06437's through postalCodes[<zip>06437</zip>].
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36551377
I think the problem still is the fact that we're getting an XML object reference rather than the actual _value_ (06437).

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/xml/XMLNode.html?filter_flash=cs5&filter_flashplayer=10.2&filter_air=2.6#nodeValue

XMLNode.nodeValue
0
 
LVL 11

Expert Comment

by:petiex
ID: 36551877
After playing with this a while, I find you can access counts for zipcodes that start with 0 by putting the value in quotes: postalCodes["06437"] or by appending the string zero to the value: postalCodes["0"+06437]. I think that the fact that postalCodes[<zip>06437</zip>] also retrieves the value is due to the compiler's converting the value in square brackets from an xml value to a string rather than the possibility of the object having a property name that is itself xml. By the same token, postalCodes[06437] likely compiles to postalCodes["6437"], for which, of course, no values were assigned.
0
 

Author Comment

by:petersego
ID: 36553356
Thank you, that is good to know.
But Im also having another problem.
When trying to delegate the zip-codes to a map, only the last item in the xml is delegated.
Remember that zipcode holds the index of the zipcodes - equal to
postList[i].toString();

Open in new window

This is how I wanted to delegate the colors:
if(postalCodes[zipcode]>=2){
   var baseColor:ColorTransform = postdk.getChildAt(p).transform.colorTransform;
   baseColor.color=TwoColor;
   postdk.getChildAt(p).transform.colorTransform = baseColor;
}
else{
   var baseColor2:ColorTransform = postdk.getChildAt(p).transform.colorTransform;
   baseColor2.color=OneColor;
   postdk.getChildAt(p).transform.colorTransform = baseColor2;
}

Open in new window

There is no doubt that zipcode is recognized because the colour shifts depending on if the last item in the xml is a single representation or not.

I realize that this might be a brand new question, so I will award new points in a new question.
0
 

Author Comment

by:petersego
ID: 36553667
Forget the last comment/question. I forgot that zipcode no longer was inside the loop.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

I know the transition can be hard. We got used to the ease of use ActionScript 2 had, but honestly, it became problematic later on, especially if designers were involved in the project and found it easy to add code as they saw fit. So, this artic…
In my long career of working as an actionscript developer, I had spent sleepless night often working hard to solve some small problems which actually took a lot of my development time; later found out the solutions to be a line or two. Here are s…
The goal of the tutorial is to teach the user how to how to load their YouTube profile onto Flash Media Live Encoder.
The goal of the tutorial is to teach the user how to select the video input device. Make sure you have an input device that in connected and work and recognized by Adobe Flash Media Live Encoder and select it in the “video input” menu.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now