Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/415.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用React Native对电话联系人进行排序_Javascript_React Native_Sorting_React Native Flatlist - Fatal编程技术网

Javascript 使用React Native对电话联系人进行排序

Javascript 使用React Native对电话联系人进行排序,javascript,react-native,sorting,react-native-flatlist,Javascript,React Native,Sorting,React Native Flatlist,我的react本机应用程序向拥有我的应用程序的用户电话簿中的联系人发送类似于消息的内容。因此,当用户注册时,他们只注册使用我的应用程序,他们只注册他们的电话号码。当需要向联系人发送消息时。我访问他们的电话簿,并将其与Rails后端中的号码进行比较。如果他们匹配用户电话簿中的号码。然后我从他们的电话簿中提取姓名,并将其与号码一起显示给他们,以便向该联系人发送信息 问题是它们是随机排序的。我要他们按字母顺序排序。数字来自BE(Rails),名称来自FE(React Native)应用程序。我知道我需

我的react本机应用程序向拥有我的应用程序的用户电话簿中的联系人发送类似于消息的内容。因此,当用户注册时,他们只注册使用我的应用程序,他们只注册他们的电话号码。当需要向联系人发送消息时。我访问他们的电话簿,并将其与Rails后端中的号码进行比较。如果他们匹配用户电话簿中的号码。然后我从他们的电话簿中提取姓名,并将其与号码一起显示给他们,以便向该联系人发送信息

问题是它们是随机排序的。我要他们按字母顺序排序。数字来自BE(Rails),名称来自FE(React Native)应用程序。我知道我需要将它们都放入FE上某种类型的数组中,然后对它们进行排序。不幸的是,我的Javascript和React本地技能仍然有些薄弱。理论上我知道我需要做什么,但我似乎无法让它发挥作用

当然,我省略了很多代码,只留下了重要的部分。第一部分显示了三个函数“parseContacts、fetchContacts和getContactName”

“fetchContacts”从BE中获取电话号码。“getContactName”从电话簿中获取姓名。“parseContacts”按照tin上的说明进行操作

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 : ''
      }
    }
  }
下面的代码是我在列表中呈现手机上的姓名和号码的代码

            <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>
                  )}
                />

{this.state.contacts.length?
index.toString()}
renderItem={({item})=>(
{this.getContactName(item.phone_number)}
{项目.电话号码}
{item.selected?
此.removeContact(项目)}>
:
此选项。选择联系人(项目)}>
}
)}
/>

希望到目前为止我所做的一切都很清楚。我现在想我需要的是另一个函数,将名称和数字拉到一起,并在渲染之前对它们进行排序。至少我是这么想的。也许排序需要在渲染中完成。我不是100%。我已经尝试了两天的各种方法,但似乎都没有得到它按字母顺序对联系人列表进行排序。任何帮助都将不胜感激。

您需要将姓名放入电话号码数组中,然后进行排序…目前,您在呈现电话号码时会获取联系人的姓名,因此无法事先进行排序

    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 })
    }
if(res.response){
console.log('contacssst:',res.contact_list);
const contacts=res.contact\u list.map((contact)=>{
//循环浏览联系人并添加找到的显示名称。
contact.displayName=this.getContactName(contact.phone\u号码);
回接;
});
//使用displayName属性进行排序。
联系人排序((a,b)=>{
如果(a.displayName>b.displayName){
返回1;
}
if(a.displayName
然后在视图中可以直接访问item.displayName


我很快编写了排序函数,不太确定排序是否正确。

您需要将姓名放入PhoneNumber数组中,然后进行排序…目前,在呈现电话号码时,您会获取联系人的姓名,因此无法事先进行排序

    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 })
    }
if(res.response){
console.log('contacssst:',res.contact_list);
const contacts=res.contact\u list.map((contact)=>{
//循环浏览联系人并添加找到的显示名称。
contact.displayName=this.getContactName(contact.phone\u号码);
回接;
});
//使用displayName属性进行排序。
联系人排序((a,b)=>{
如果(a.displayName>b.displayName){
返回1;
}
if(a.displayName
然后在视图中可以直接访问item.displayName


我很快编写了排序函数,不太确定排序是否正确。

@salketter让我非常接近正确答案。我使用了另一种排序方法。最后一次设置状态时,我只需要设置联系人。再次感谢

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 })
}

@萨尔克特让我非常接近正确答案。我使用了不同的排序方式结束。最后设置状态我只需要设置联系人。再次感谢

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 })
}

它仍然给我相同的结果。我仍然得到名称,但他们没有排序。我非常感谢你的帮助。你认为我可能做错了什么吗?item.displayName正在提取名称。只是没有排序。只是更新。如果我控制台.log(联系人)就在该集合的上方。在底部显示状态。它实际上是按字母顺序返回名称。因此,我需要访问不同的视图才能看到它们。item.displayName或item.contacts.displayName或item.contacts不起作用。第一个仅显示未排序的列表。其他两个为空。我不知道如何显示列表得到返回的列表的顺序正确。它仍然给我相同的结果。我仍然得到名称,但它们没有排序。我非常感谢您的帮助。您认为我可能做错了什么吗?item.displayName正在提取名称。只是没有排序。只是更新。如果我控制台.log(联系人)就在这个集合的上方。在底部是State。它实际上是按字母顺序返回名称。