Sorting a Flex Array - arrays

I have created an array as shown below
protected function getMyArray(dataArray:Array):Array
{
var labelList:Array=new Array;
for each (var property:Object in dataArray)
{
if (labelList[property.bucketTime] != property.bucketTime)
labelList[property.bucketTime]=property.bucketTime;
}
return labelList;
}
Is it possible to sort the array labelList based on property.bucketTime?
Edit: Sample input dataArray will be like this :
var tempObj:Object = new Object;
tempObj.bucketTime = DateField.stringToDate("30-01-2010", "DD-MM-YYYY").time;
tempObj.score = 76;
dataArray.addItem(tempObj);
tempObj = new Object;
tempObj.bucketTime = DateField.stringToDate("13-02-2010", "DD-MM-YYYY").time;
tempObj.score = 21;
dataArray.addItem(tempObj);
tempObj = new Object;
tempObj.bucketTime = DateField.stringToDate("30-03-2010", "DD-MM-YYYY").time;
tempObj.score = 10;
tempArry.addItem(tempObj);

Unless bucketTime is a number; then you aren't actually populating the array. You're just adding properties to the Array Object, almost like it were a Dictionary. I've seen a Dictionary called Associative Array's and Structures in other languages.
If that is the case, an you're using the Array class as a dictionary, then there is no way to sort it. The very nature of such a structure is that they are not sortable.
However, if property.bucketTime is a number, and you are trying adding items to the array as if they were an array, you can sort using the Array.sort or Array.sortOn methods.

Atlast I sorted the labelList Array.Please find my solution below. Let me know if there is any better way to achieve this.
var termObject:Object = ObjectUtil.getClassInfo(labelList);
var termsArray:Array = termObject.properties;
var sortedColumnArray:Array = new Array;
for each(var term:Object in termsArray){
if(labelList.hasOwnProperty(term)){
sortedColumnArray.push(labelList[term]);
}
}

Related

Problems with multidimensional arrays in Typescript and Angular

I have this code to fill a multidimensional array
filaCalendario: string[] = [];
filasCalendario: string[][] = [];
crearFila(){
for (let actividad of this.listaActividades) {
this.filaCalendario.push(actividad.faseId);
this.filaCalendario.push(actividad.descripcion);
for (let dia of this.cabeceraCalendarioNumeroDiaDeLaQuincena) {
if (new Date(actividad.fecha).getDate() == dia) {
this.filaCalendario.push(actividad.duracion.toString());
}
else {
this.filaCalendario.push("");
}
}
this.filasCalendario.push(this.filaCalendario);
this.filaCalendario.splice(0);
}
console.log(this.filasCalendario);
}
}
After push filaCalendario into filasCalendario I delete the elements of filaCalendario to push the new values but after
this.filasCalendario.push(this.filaCalendario);
this.filasCalendario is empty too
After push it the first time i get this
And after splice filaCalendario I get this
Any idea, please?
Thanks
Your problem is this: When you do a someArray.push(x) operation you are not creating a new string and adding that to the array. You are adding a reference to that string.
So when you do
this.filaCalendario.splice(0);
You are truncating the filaCalendario array. The reference to that array will also reflect the truncated array. Try:
this.filaCalendario = [];
instead. That will allocate a new array in memory and leave the reference to the prior array untouched.

Compare an array within an object with an array within another object - both objects within the same parent array

I have an array of objects (~12 000 objects) each object looks like:
{id: num, name: "first last", identifiers: [num, num, num, num]}
What I need to do is compare each object with each other object within the array and if two objects have a matching identifier, I need to create another object in a completely separate array linking the two object ids.
When each object only had one number as an identifier, I could do it quite easily with:
let data = [*arr with objects*];
let nodes = data;
let len = nodes.length;
let links = [];
for (let i = 0; i < len; i++) {
let arrTest = nodes.findIndex((e) => e.identifiers === data[i].identifiers);
if (arrTest !== -1) {
const newLink = new Object();
newLink.source = nodes[arrTest].id;
newLink.target = data[i].id;
links.push(newLink);
}
}
However, with identifiers now being arrays I'm lost on the logic to receive the same outcome. What seems to make it harder for some attempts I've made is that some objects still only have a single number as an identifier - throwing errors if array methods such as .length are used??
My only thought right now is to create a new array with each identifier as a separate object with the id it originated from such as:
{identifier: num, id: num}
from this, it would just be a case of iterating through that array and connecting and creating new links through a similar method as above.
Wanted to know if there was a more efficient method, my JS is fairly limited and just really started making apps with it.
Any advice would be greatly appreciated.
Cheers
You could check the type of the identifier by doing something like-
if (typeof identifier === "number") {
// do what you are already doing
} else {
// it's an array so you can loop here
}
Using a dictionary to quickly access all other (previous) items with the same identifier
let data = [* arr with objects *];
const itemsByIdentifiers = {};
let links = [];
for (let item of data) {
// get (or create) the list with the recorded items for this identifier
let others = itemsByIdentifiers[item.identifiers] ||= [];
// iterate over that list and add the links
for (let other of others) {
links.push({
source: other.id,
target: item.id
});
}
// add myself to the list, so future items can find me and link to me
others.push(item);
}

Using functions in arrays Swift

i use the following function to retrieve a random person from an array:
func getRandomPerson() -> String{
if(personArray.isEmpty){
return ""
} else {
var tempArray: [String] = []
for person in personArray{
tempArray += [person.getName()]
}
var unsignedArrayCount = UInt32(tempArray.count)
var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
var randomNumber = Int(unsignedRandomNumber)
if tempArray.isEmpty {
return ""
} else {
return tempArray[randomNumber]
}
}
}
I would like to use this function inside an array of strings, Like this:
var theDares: [String] = ["Dare1 \(getRandomPerson())", "Dare2", "Dare3", "Dare4", "Dare5"]
But when i use the functions, it only runs the function once. Can you make the function run everytime you use the "Dare1" in this instance.
Thanks in advance
I think you are asking if you can set up your array so every time you fetch the object at index 0, it re-builds the value there.
The short answer is no. Your code is creating an array of strings, and the item at index 0 is built ONCE using a function call.
However, it is possible to make a custom class implement the subscript operator. You could create a custom object that looks like an array and allows you to index into it using an Int index. In response to the index operator you could run custom code that built and returned a random string.
Since it sounds like you're a beginning programmer creating a custom class the implements the subscript operator might be beyond your current abilities however.
Try like this:
let personArray = ["John", "Steve", "Tim"]
var randomPerson: String {
return personArray.isEmpty ? "" : personArray[Int(arc4random_uniform(UInt32(personArray.count)))]
}
println(randomPerson) // "Steve"

Loop through an array of objects and add only the value to another array. Knockout

friends. I have the following issue. I have two observable arrays.
self.NamesArray= ko.observableArray([{"name: John"}, {"name: Mario"}]);
and
self.ValueArray = ko.observable([]);
I would like to loop through the NamesArray and add only the name values to the ValueArray.
So the output ValueArray should contain the following elements in the end:
{John, Mario}
How can this happen? I am very new to JS and I am just researching the Knockout library. Any help with working example will be greatly appreciated. Thanks.
Fiddle: http://jsfiddle.net/PsyComa/RfWVP/
This really depends on your intention behind doing this.
If you want do to this just once, simply iterate over the first array:
// Load current values of the observables
var n = self.NamesArray(), v = self.ValueArray();
// Push all names from n to v
for (var i = 0; i < n.length; i++) {
v.push( n[i].name );
}
// Update the "values" observable
self.ValueArray(v);
The downside with this is that "ValueArray" does not get updated whenever "NamesArray" changes. If you want "ValueArray" to be an array containing all names that can be found in "NamesArray" (and only those!), you can use a computed observable instead:
self.ValueArray = ko.computed(function() {
var n = self.NamesArray(), v = [];
// ...same for loop as above...
return v;
});

flash as3 how to prevent an item from being added to an array if it already exists in the array

I know how to remove duplicates from an array, but what I'm trying to do is prevent an item from ever being added to an array in the first place if it already exists. I'm pulling in data from an xml feed in a loop, and I thought that searching for that values index would work, but no matter what, the index is always -1. Here's my code:
var yearArr:Array = new Array();
for (var i=0;i<numCovers;i++){
var coverRef = xmlObj.cover[i];
var coverClip:MovieClip = new MovieClip();
coverClip.year = coverRef.#year;
if (yearArr.indexOf(coverClip.year === -1)){
yearArr.push (coverClip.year);
}
}
Maybe I'm misunderstanding the indexOf function, but I thought it was supposed to return -1 if a value did not exist in an array. What am I doing wrong?
Here's the solution I came up with:
var yearArr:Array = new Array();
for (var i=0;i<numCovers;i++){
var coverRef = xmlObj.cover[i];
var coverClip:MovieClip = new MovieClip();
coverYear = coverRef.#year;
addCoverYear(coverYear);
}
function addCoverYear(coverYear:int):void {
if (yearArr.indexOf(coverYear) == -1){
yearArr.push(coverYear);
}
}
you can reduce an array by passing everything to a dictionary, which will automatically remove redundancies. then pass the dictionary back as a new array.
//Reduce Array
private function reduceArray(array:Array):Array
{
var dictionary:Dictionary = new Dictionary();
for each (var element:String in array)
dictionary[element] = true;
var result:Array = new Array();
for (var key:String in dictionary)
result.push(key);
dictionary = null;
return result;
}
Your code is almost fine. The problem is that an E4X property .#year is not a literal string (I'm not sure right now, but I believe it's an XMLList object). That's why the indexOf call will keep returning -1, because it is looking for a duplicate of that object, not a string. E4X will convert it to a string as soon as you put it somewhere where only strings can go, but until that time it is something else.
If you rewrite your code like this, it should work right away:
var yearArr:Array = new Array();
for each (var coverRef : XML in xmlObj.cover){
var year : String = coverRef.#year; // force the property to be a string
if (yearArr.indexOf(year) < 0){
yearArr.push (year);
}
}
There were also a few other optimizations you could do to your code. The new MovieClip() part wasn't used, not all variables were strongly typed and by using a for each loop, you can state much clearer what objects you're looping through.
Here is what you could do, if for example, you have an array of strings.
var ItemList:Array = new Array();
for each(var Item:String in UseYourXMLFeed)
{
if(ItemList.indexOf(Item) == -1)
{
ItemList.push(Item);
}
}
Edit:
Anyways, your real answer is in the comment by Sam.

Resources