【问题标题】:Importing from second array in Swift从 Swift 中的第二个数组导入
【发布时间】:2014-12-24 01:23:39
【问题描述】:

我有 2 个数组,1 个是主数组 (bookArray),另一个是更新列表 (stockBooksArray)。我使用下面的循环使用两个数组中都存在的唯一记录 (isbn) 将新数据导入到浪费数组中。

有没有办法提高下面循环的性能?

更新数组可以包含与主节点不同的计数,有时更多,有时更少。

for i in 0...stockBooksArray.count {


        let StockFiltered = stockBooksArray.filter{$0.isbn == bookArray[i].isbn}

        if StockFiltered.count != 0 {

            bookArray[i].stockAmount = StockFiltered[0].Stock
            bookArray[i].unitCost = StockFiltered[0].Cost
            bookArray[i].dues = StockFiltered[0].dues
            bookArray[i].stockRRP = StockFiltered[0].RRP

            }
        }

谢谢, 安东尼

【问题讨论】:

  • 是否存在测量性能问题?如果不是简单的节拍复杂但稍微快一点,也不会明显更快。 “过早的优化是万恶之源”——Donald Knuth.
  • 在旧设备上完成大约需要 5-6 秒,在最新 (A8) 设备上需要 2 秒。只是想让它像发布时发生的排序一样快。
  • 如果stockBooksArraybookArray 没有的元素会怎样?如果bookArraystockBooksArray 没有的元素怎么办?简单的作业可以吗?
  • @Zaph "这不是过早的优化;它是在避免无端的悲观。" (Herb Sutter,Andrei Alexandrescu “C++ 编码标准”)
  • 是的,直到提供时间后才知道。

标签: arrays xcode swift


【解决方案1】:

是的,有。现在,您正在为每个 stockBooksArray 对象循环一次 bookArray 数组。那是 O(N*M),非常糟糕。

相反,如果您可以按 ISBN 对两个数组进行排序,那么您可以同时遍历两个数组,每个元素只访问一次,这将是 O(N)。即使您包括对它们进行排序的时间,速度也要快得多。

我很快就把下面的代码放在一起了。它假设两个数组都按 isbn 排序。我想你会发现这要快得多。

var j = 0
for book in stockBooksArray {
    while bookArray[j].isbn < book.isbn && j < bookArray.count {
        ++j;
    }
    if j == bookArray.count {
        break
    }
    else if  bookArray[j].isbn == book.isbn {
        bookArray[j].stockAmount = StockFiltered[0].Stock
        bookArray[j].unitCost = StockFiltered[0].Cost
        bookArray[j].dues = StockFiltered[0].dues
        bookArray[j].stockRRP = StockFiltered[0].RRP
    }
}

【讨论】:

    【解决方案2】:

    如果您只是添加新的,您可以获得每个 ISBN 的 NSMutableSet,执行一组 minusSet: 操作,从 stockBooksArray 中删除 bookArray ISBN,然后将生成的 ISBN 添加到 bookArray

    未经测试的概念代码,根据需要转换为 Swift:

    NSMutableSet *stockBooksSet = NSMutableSet setWithArray:[stockBooksSet valueForKey:@"isbn"];
    NSSet *booksSet = NSSet setWithArray:[bookArray valueForKey:@"isbn"];
    [stockBooksSet minusSet: booksSet];
    for (NSString *isbn in stockBooksSet) {
        // add book with ism to booksSet
    }
    

    【讨论】:

      【解决方案3】:

      使用 Daniel T. 方法更新代码。

       bookArray.sort { (lhs, rhs) in return lhs.isbn < rhs.isbn }
          stockBooksArray.sort { (lhs, rhs) in return lhs.isbn < rhs.isbn }
      
          var j = 0
          for book in stockBooksArray {
              while bookArray[j].isbn < book.isbn && j < bookArray.count {
                  ++j
              }
              if j == bookArray.count {
                  break
              }
              else if bookArray[j].isbn == book.isbn {
                  bookArray[j].stockAmount = book.Stock
                  bookArray[j].unitCost = book.Cost
                  bookArray[j].dues = book.dues
                  bookArray[j].stockRRP = book.RRP
              }
          }
      

      从 iPad2 上的 5-6 秒到几乎即时。

      非常感谢, 安东尼

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        • 2018-01-22
        • 2017-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多