在数组中创建比较

Create a comparison in an array

我正在开发一个应用程序来显示有关城市的一些信息

在数组中我有两个参数 1- 语言(我不知道有多少种) 2- 使用该语言的人数

我从服务器获取这些数据

这是 JSon

中的这两个参数
"language": "French",
"number": "12321",

这些数据和其他数据一起保存在一个数组中

我只想得到最常用的语言百分比 例如法语占 35% 我怎样才能在 swift 中做到这一点?

我们将不胜感激您的帮助。

最简单的方法是:

// Example JSON
const exampleJSON = {
  "people": [
{
"language": "French",
"number": 12321,
},
{
"language": "English",
"number": 7000,
}
]
};

// Parse it
const parsed = JSON.parse(JSON.stringify(exampleJSON));
const speakers = [...parsed.people];

// Count number of all speakers and let it be as 100%
let sumAllSpeakers = 0;
parsed.people.reduce((previous, current) => {
  sumAllSpeakers = previous.number + current.number;
  return previous;
});

// Compare fucntion
const compareSpeakers = (speaker1, speaker2) => {

  if (speaker1.number > speaker2.number) {
    return -1;
  }

   if (speaker1.number < speaker2.number) {
    return 1;
  }

  return 0;
}

// Create new array with statistic sorted from max number
const statisticsOfSpeakersInPersent = speakers
.sort((speaker1, speaker2) => compareSpeakers(speaker1, speaker2))
.map(speaker => {
  return {...speaker, ...{inPersent: speaker.number * 100 / sumAllSpeakers + '%'}}
});

希望这个例子对你有帮助。

输出:

[ { language: 'French', number: 12321, inPersent: '63.76999120128358%' }, { language: 'English', number: 7000, inPersent: '36.23000879871642%' } ]

import Foundation

let serverOutput = Data("""
[
    {
        "language": "French",
        "number": "12"
    },
    {
        "language": "English",
        "number": "10"
    }
]
""".utf8)

struct LangueUsers: Codable {
    let language: String
    let number: Int

    enum CodingKeys: CodingKey {
        case language
        case number
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        language = try container.decode(String.self, forKey: .language)
        let rawNumber = try container.decode(String.self, forKey: .number)
        guard let number = Int(rawNumber) else {
            throw DecodingError.typeMismatch(Int.self, DecodingError.Context(codingPath: [CodingKeys.number], debugDescription: "\(rawNumber) can't be convert to Int"))
        }
        self.number = number
    }
}

struct LangueUsersPercent: CustomStringConvertible {
    let language: String
    let share: Double

    init(language: String, number: Int, all: Int) {
        self.language = language
        self.share = Double(number) / Double(all)
    }

    var description: String {
        return String(format: "%@ - %0.1f%%", language, share * 100)
    }
}

let decoder = JSONDecoder()
//1
var output = try decoder.decode([LangueUsers].self, from: serverOutput)
//2
let allUser = output.reduce(0) { (reult, languageUsers) -> Int in
    reult + Int(languageUsers.number)
}
//3
output.sort { (lhs, rhs) -> Bool in
    lhs.number > rhs.number
}
//4
let response = output.map {
    LangueUsersPercent(language: [=10=].language, number: [=10=].number, all: allUser)
}
print(response[0])

代码假定服务器的输出在 serverOutput 变量中。所以需要完成你的任务的步骤:

  1. 使用 swift 可编码将您的 JSON 解码为 swift 结构(称为 LangueUsers)。请记住,默认情况下它不会将字符串值转换为 int,因此我必须创建一个自定义 init(from decoder: Decoder) 初始化程序
  2. 计算所有用户的总和(您可以像我的示例一样使用 for 循环或 reduce 来完成)
  3. 对您的列表进行排序,因此用户最多的语言排在第一位
  4. 这一步是可选的,但我添加了一个单独的结构来帮助我们生成输出,在这一步中,我们将输入结构重写为输出结构

希望您清楚这一点。如果您有任何问题,请告诉我。