使用 React Native 对 Phone 联系人进行排序
Sorting Phone Contacts With React Native
我的本机反应应用程序向用户 phone 簿中有我的应用程序的联系人发送类似于消息的内容。因此,当用户注册时,他们只注册使用我的应用程序,他们只注册他们的 phone 号码。在向联系人发送消息时。我访问他们的 phone 书并将其与我在 Rails 后端中的数字进行比较。如果它们与用户 phone 书中的号码匹配。然后我从他们的 phone phone 簿中提取姓名并将其与号码一起显示给他们,以便向该联系人发送消息。
问题是它们随机排序。我希望他们按字母顺序排序。数字来自 BE (Rails),名称来自 FE (React-Native) 应用程序。我知道我需要将它们都放入 FE 上的某种数组中,然后对它们进行排序。不幸的是,我的 Javascript 和 React-Native 技能仍然有些薄弱。理论上我知道我需要做什么,但我似乎无法让它发挥作用。
我当然遗漏了相当多的代码,只留下了重要的部分。第一部分展示了三个函数“parseContacts, fetchContacts, getContactName.
"fetchContacts" 从 BE 获取 phone 号码。 "getContactName" 从 phone 的 phone 本书中获取名称。 "parseContacts" 言出必行。
async parseContacts(contacts) {
let numbers = [];
contacts.forEach(element => {
element.contactNumber = element.phoneNumbers[0] ? element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '') : '';
element.phoneNumbers[0] ? numbers.push(element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '')) : null;
});
this.setState({ phoneContacts: contacts })
return numbers;
}
async fetchContacts(contacts) {
let phoneNumbers = await this.parseContacts(contacts);
if (phoneNumbers.length) {
this.setState({ isLoadingNumbers: true })
let data = {
"numbers": phoneNumbers,
}
try {
let res = await postFunctionWithAuthToken(`${baseUrl}/contact/check`,
JSON.stringify(data), this.state.authToken);
if (res.response) {
console.log('contacssssst: ', res.contact_list);
this.setState({ contacts: res.contact_list, isLoadingNumbers: false })
} else {
this.setState({ isLoadingNumbers: false })
Alert.alert('Error', `${res.error}! try again.`);
}
} catch (error) {
console.log('error: ', error);
this.setState({ isLoadingNumbers: false })
Alert.alert('Error', 'request failed! try again.')
}
}
}
getContactName(number) {
const { phoneContacts, countryCode } = this.state;
if (phoneContacts.length) {
let index = phoneContacts.findIndex(element => {
let parsedNumber = element.phoneNumbers[0] ? element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '') : "";
if (parsedNumber) {
if (parsedNumber.slice(0, 1) === "0") {
if (parsedNumber.slice(1, 2) === "0") {
if (parsedNumber.substring(2) === number ||
parsedNumber.substring(2).replace(`${countryCode}0`, countryCode) === number) {
return number;
}
} else {
return countryCode + parsedNumber.substring(1) === number;
}
} else {
// console.log('nummm: ', parsedNumber, number);
// return parsedNumber === number;
if (parsedNumber === number ||
parsedNumber.replace(`${countryCode}0`, countryCode) === number) {
return number;
}
}
}
});
if (Platform.OS === 'ios') {
return index >= 0 ? phoneContacts[index].givenName : ''
} else {
return index >= 0 ? phoneContacts[index].displayName : ''
}
}
}
下面的代码是我在列表中 phone 上呈现名称和号码的地方。
<View style={styles.container}>
{this.state.contacts.length ?
<FlatList
data={this.state.contacts}
extraData={this.state}
numColumns={1}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<View style={styles.itemContainer}>
<View>
<Text style={{ color: '#000', fontSize: 20 }}>
{this.getContactName(item.phone_number)}</Text>
<Text style={{ color: '#000' }}>
{item.phone_number}</Text>
</View>
{item.selected ?
<TouchableOpacity onPress={() => this.removeContact(item)}>
<Icon name={"ios-add-circle"} size={26} color={primaryColor} />
</TouchableOpacity>
:
<TouchableOpacity onPress={() => this.selectContact(item)}>
<Icon name={"ios-add-circle"} size={26} color={'grey'} />
</TouchableOpacity>
}
</View>
)}
/>
希望到目前为止我所做的很清楚。无论如何,我现在需要什么。是另一个函数,用于将名称和数字放在一起并在我呈现它们之前对它们进行排序。至少那是我的想法。也许排序需要在渲染中完成。我不是 100%。两天来我一直在尝试各种方法,但似乎无法让它按字母顺序对联系人列表进行排序。任何帮助都将不胜感激。
您需要将姓名放入 phone 号码数组中,然后排序...目前您在呈现 phone 号码时获取联系人姓名,因此无法排序事先...
if (res.response) {
console.log('contacssssst: ', res.contact_list);
const contacts = res.contact_list.map((contact)=>{
//Loop through the contacts and add the display name found.
contact.displayName = this.getContactName(contact.phone_number);
return contact;
});
//Sort using the displayName property.
contacts.sort((a,b)=>{
if(a.displayName > b.displayName){
return 1;
}
if(a.displayName < b.displayName){
return -1;
}
return 0;
});
this.setState({ contacts: res.contact_list, isLoadingNumbers: false })
}
那么在你看来可以直接访问item.displayName.
我很快就写了排序函数,不太确定排序是否正确。
@salketer 让我非常接近正确答案。我结束了使用不同的排序方式。还有最后一个 setState 我只需要设置联系人。再次感谢。
if (res.response) {
console.log('contacts: ', res.contact_list);
const contacts = res.contact_list.map((contact)=>{
contact.displayName = this.getContactName(contact.phone_number);
return contact;
});
contacts.sort((a, b) => a.displayName.localeCompare(b.displayName));
console.log('contacts_returned: ', contacts);
this.setState({ contacts, isLoadingNumbers: false })
}
我的本机反应应用程序向用户 phone 簿中有我的应用程序的联系人发送类似于消息的内容。因此,当用户注册时,他们只注册使用我的应用程序,他们只注册他们的 phone 号码。在向联系人发送消息时。我访问他们的 phone 书并将其与我在 Rails 后端中的数字进行比较。如果它们与用户 phone 书中的号码匹配。然后我从他们的 phone phone 簿中提取姓名并将其与号码一起显示给他们,以便向该联系人发送消息。
问题是它们随机排序。我希望他们按字母顺序排序。数字来自 BE (Rails),名称来自 FE (React-Native) 应用程序。我知道我需要将它们都放入 FE 上的某种数组中,然后对它们进行排序。不幸的是,我的 Javascript 和 React-Native 技能仍然有些薄弱。理论上我知道我需要做什么,但我似乎无法让它发挥作用。
我当然遗漏了相当多的代码,只留下了重要的部分。第一部分展示了三个函数“parseContacts, fetchContacts, getContactName.
"fetchContacts" 从 BE 获取 phone 号码。 "getContactName" 从 phone 的 phone 本书中获取名称。 "parseContacts" 言出必行。
async parseContacts(contacts) {
let numbers = [];
contacts.forEach(element => {
element.contactNumber = element.phoneNumbers[0] ? element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '') : '';
element.phoneNumbers[0] ? numbers.push(element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '')) : null;
});
this.setState({ phoneContacts: contacts })
return numbers;
}
async fetchContacts(contacts) {
let phoneNumbers = await this.parseContacts(contacts);
if (phoneNumbers.length) {
this.setState({ isLoadingNumbers: true })
let data = {
"numbers": phoneNumbers,
}
try {
let res = await postFunctionWithAuthToken(`${baseUrl}/contact/check`,
JSON.stringify(data), this.state.authToken);
if (res.response) {
console.log('contacssssst: ', res.contact_list);
this.setState({ contacts: res.contact_list, isLoadingNumbers: false })
} else {
this.setState({ isLoadingNumbers: false })
Alert.alert('Error', `${res.error}! try again.`);
}
} catch (error) {
console.log('error: ', error);
this.setState({ isLoadingNumbers: false })
Alert.alert('Error', 'request failed! try again.')
}
}
}
getContactName(number) {
const { phoneContacts, countryCode } = this.state;
if (phoneContacts.length) {
let index = phoneContacts.findIndex(element => {
let parsedNumber = element.phoneNumbers[0] ? element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '') : "";
if (parsedNumber) {
if (parsedNumber.slice(0, 1) === "0") {
if (parsedNumber.slice(1, 2) === "0") {
if (parsedNumber.substring(2) === number ||
parsedNumber.substring(2).replace(`${countryCode}0`, countryCode) === number) {
return number;
}
} else {
return countryCode + parsedNumber.substring(1) === number;
}
} else {
// console.log('nummm: ', parsedNumber, number);
// return parsedNumber === number;
if (parsedNumber === number ||
parsedNumber.replace(`${countryCode}0`, countryCode) === number) {
return number;
}
}
}
});
if (Platform.OS === 'ios') {
return index >= 0 ? phoneContacts[index].givenName : ''
} else {
return index >= 0 ? phoneContacts[index].displayName : ''
}
}
}
下面的代码是我在列表中 phone 上呈现名称和号码的地方。
<View style={styles.container}>
{this.state.contacts.length ?
<FlatList
data={this.state.contacts}
extraData={this.state}
numColumns={1}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<View style={styles.itemContainer}>
<View>
<Text style={{ color: '#000', fontSize: 20 }}>
{this.getContactName(item.phone_number)}</Text>
<Text style={{ color: '#000' }}>
{item.phone_number}</Text>
</View>
{item.selected ?
<TouchableOpacity onPress={() => this.removeContact(item)}>
<Icon name={"ios-add-circle"} size={26} color={primaryColor} />
</TouchableOpacity>
:
<TouchableOpacity onPress={() => this.selectContact(item)}>
<Icon name={"ios-add-circle"} size={26} color={'grey'} />
</TouchableOpacity>
}
</View>
)}
/>
希望到目前为止我所做的很清楚。无论如何,我现在需要什么。是另一个函数,用于将名称和数字放在一起并在我呈现它们之前对它们进行排序。至少那是我的想法。也许排序需要在渲染中完成。我不是 100%。两天来我一直在尝试各种方法,但似乎无法让它按字母顺序对联系人列表进行排序。任何帮助都将不胜感激。
您需要将姓名放入 phone 号码数组中,然后排序...目前您在呈现 phone 号码时获取联系人姓名,因此无法排序事先...
if (res.response) {
console.log('contacssssst: ', res.contact_list);
const contacts = res.contact_list.map((contact)=>{
//Loop through the contacts and add the display name found.
contact.displayName = this.getContactName(contact.phone_number);
return contact;
});
//Sort using the displayName property.
contacts.sort((a,b)=>{
if(a.displayName > b.displayName){
return 1;
}
if(a.displayName < b.displayName){
return -1;
}
return 0;
});
this.setState({ contacts: res.contact_list, isLoadingNumbers: false })
}
那么在你看来可以直接访问item.displayName.
我很快就写了排序函数,不太确定排序是否正确。
@salketer 让我非常接近正确答案。我结束了使用不同的排序方式。还有最后一个 setState 我只需要设置联系人。再次感谢。
if (res.response) {
console.log('contacts: ', res.contact_list);
const contacts = res.contact_list.map((contact)=>{
contact.displayName = this.getContactName(contact.phone_number);
return contact;
});
contacts.sort((a, b) => a.displayName.localeCompare(b.displayName));
console.log('contacts_returned: ', contacts);
this.setState({ contacts, isLoadingNumbers: false })
}