Order a Nsurl Array

Order a NSURL array

As you want to sort the files by the number you have to parse first the path to achieve it, so let's suppose we have the following array of NSURL objects:

var urls = [NSURL(string: "file:///path/to/user/folder/2.PNG")!, NSURL(string: "file:///path/to/user/folder/100.PNG")!, NSURL(string: "file:///path/to/user/folder/101.PNG")!, NSURL(string: "file:///path/to/user/folder/1.PNG")! ]

We can use the pathComponents property to extract an array with all the components in the path for a NSURL (e.g ["/", "path", "to", "user", "folder", "2.PNG"]).

If we see we can order the files by the last element in the array that is the filename removing the extension and the dot("."), in this case the number. Let's see how to do it in the following code:

urls.sortInPlace {

// number of elements in each array
let c1 = $0.pathComponents!.count - 1
let c2 = $1.pathComponents!.count - 1

// the filename of each file
var v1 = $0.pathComponents![c1].componentsSeparatedByString(".")
var v2 = $1.pathComponents![c2].componentsSeparatedByString(".")

return Int(v1[0]) < Int(v2[0])
}

In the above code we use the function sortInPlace to avoid create another array with the elements sorted, but can you use sort instead if you want. The another important point in the code is the line return Int(v1[0]) < Int(v2[0]), in this line we have to convert the number in the string to a real number, because if we compare the two strings "2" and "100" the second one is less than greater than because the string are compared lexicographically.

So the the array urls should be like the following one:

[file:///path/to/user/folder/1.PNG, file:///path/to/user/folder/2.PNG, file:///path/to/user/folder/100.PNG, file:///path/to/user/folder/101.PNG]

EDIT:

The two functions pathComponents and componentsSeparatedByString increase the space complexity of the sortInPlace algorithm, if you can asure that the path for the files always will be the same except it's filename that should be a number you can use instead this code:

urls.sortInPlace { $0.absoluteString.compare(
$1.absoluteString, options: .NumericSearch) == .OrderedAscending
}

I hope this help you.

Sorting an array of NSURL objects by creation date

EDIT : Better answer

If that doesn't work, you will have to write your own comparator block and get the dates to compare manually :(

[cacheContents sortUsingComparator:^ (NSURL *a, NSURL *b) {
// get the two dates
id da = [[a resourceValuesForKeys:[NSArray arrayWithObject:NSURLCreationDateKey] error:nil] objectForKey:NSURLCreationDateKey];
id db = [[b resourceValuesForKeys:[NSArray arrayWithObject:NSURLCreationDateKey] error:nil] objectForKey:NSURLCreationDateKey];

// compare them
return [da compare:db];
}];

(Same disclaimer still applies but I'm not even sure that will compile ;) - you get the idea though!)


Here is my first answer (included here for posterity but mostly it just shows how important it is to read the question properly :)

It's because you're getting an array of NSURL objects; these don't have a NSURLCreationDateKey property.

Try this (disclaimer - not 100% it will work)

NSString *key = [NSString stringWithFormat:@"fileAttributes.%@", NSURLCreationDateKey];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:key ascending:YES];

Your key to sort by is a property of the fileAttributes dictionary which is, in turn, a property of your enumerator.

How to get only the filename of a NSUrl array

First of all I have a déjà vu

Second of all do not get only the filename of a NSUrl array. You will lose the ability to sort the files by creation date.


You cannot filter an array of NSURL with a predicate, you must filter the files in a loop.

To use the filtered array as a data source first create a property in the .h file

@property NSMutableArray<NSURL *> *files; 

In the .m file create a separate method to sort the files

- (void)sortFilesByCreationDateAscending:(BOOL)ascending
{
[self.files sortUsingComparator:^(NSURL *lURL, NSURL *rURL) {
NSDate *lDate, *rDate;
[lURL getResourceValue:&lDate forKey:NSURLCreationDateKey error:nil];
[rURL getResourceValue:&rDate forKey:NSURLCreationDateKey error:nil];
return ascending ? [lDate compare:rDate] : [rDate compare:lDate];
}];
}

Get the files, filter them and sort them in viewDidLoad. Then reload the table view

- (void)viewDidLoad {
[super viewDidLoad]:
self.files = [[NSMutableArray alloc] init];
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentDirectoryURL = [fileManager URLForDirectory:NSDocumentDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:false
error:nil];

NSArray<NSURL *> *fileURLs = [fileManager contentsOfDirectoryAtURL:documentDirectoryURL
includingPropertiesForKeys:@[NSURLCreationDateKey]
options:0
error:&error];
if (error) {
NSLog(@"%@", error);
return;
}
for (NSURL *anURL in fileURLs) {
if ([anURL.pathExtension isEqualToString:@"csv"]) {
[self.files addObject: anURL];
}
}
[self sortFilesByCreationDateAscending:YES];
[self.tableView reloadData];
}

In numberOfRowsInSection return self.files.count

In cellForRowAtIndexPath get the URL for the index path and display the file name

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
static NSString *simpleTableIdentifier = @"SimpleTableItem";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier forIndexPath: indexPath];
NSURL *url = self.files[indexPath.row];
cell.textLabel.text = url.lastPathComponent;
return cell;
}

To sort the files in the other direction call sortFilesByCreationDateAscending with appropriate BOOL value and reload the table view.

Sorting arrays of file attributes by their creation date in Swift

You should not use multiple arrays for this but instead wrap your values in a custom struct

struct FileInfo {
let url: URL
let name: String
let path: String //this is not really needed, you can get it from the url
let date: Date
}

and have one array for this

var files: [FileInfo]()

and create your struct instance and append it

files.append(FileInfo(url: fileURL, name: name, path: path, date: date)

Sorting will now be trivial so after the for loop you do

files.sort(by: { $0.date < $1.date })

This sorts in ascending order, not sure which one you want.

Finding the index of 'NSURL item' in 'NSURL array'

let index = array2.indexOf { $0.absoluteString == array1[2].absoluteString }

Swift - Sorting url content into an array

The preferred way is enumerateLinesUsingBlock with NSString

var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding)!
var lines:[String] = []
urlContent.enumerateLinesUsingBlock { line, _ in
lines.append(line)
}
println(lines)

In this specific case, you can simply split by "\n":

var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding) as String
var lines = urlContent.componentsSeparatedByString("\n")
if lines.last == "" {
// The last one is empty string
lines.removeLast()
}

But in general, the line separator may not be "\n". see this document:

A line is delimited by any of these characters, the longest possible
sequence being preferred to any shorter:

  • U+000D (\r or CR)
  • U+2028 (Unicode line separator)
  • U+000A (\n or LF)
  • U+2029 (Unicode paragraph separator)
  • \r\n, in that order (also known as CRLF)

enumerateLinesUsingBlock can handle all of them.

How get Single Url From an Array of urls?

As Julian Kniephoff rightly mentioned, you are printing each URL in the for loop, thus you cannot access one particular one. However, there is also another issue, in that you are replacing the urls array with the latest url each time.

To solve this, simply replace the line self.urls = [urimage] with self.urls.append(urimage).

You can then access a particular image outside the for loop by doing something like self.urls[1].

This is also why printing the count of the array returns 1, since each time around you are setting the array to just the one latest element in the loop.

In the end, your code may look something like this

url = NSURL(string: "http://xxxxxxxxxxx.com/api/?slider=uij6sdnb")
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url) {(data, response, error) -> Void in
do {
let records = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
for record in records {
//let urlid = Int(record["slide_id"] as! String)
let urimage = record["slide_url"] as! String
self.urls.append(urimage)
}
print(self.urls[1]) //Prints http://sdkladlkasjd2.jpg
}
catch {
print("Json Error")
}
//print(self.urls[1])
}

task.resume()


Related Topics



Leave a reply



Submit