最好的 c# 语法/成语,从 Facebook 读取朋友数组

Posted

技术标签:

【中文标题】最好的 c# 语法/成语,从 Facebook 读取朋友数组【英文标题】:best c# syntax/idiom, reading array of friends from Facebook 【发布时间】:2014-06-19 08:14:40 【问题描述】:

在 c# 中,我只是从 FB api 中获取“/me/friends”,

private void FacebookFriends()
    
    FB.API("/me/friends", HttpMethod.GET, FBAPIFriendsCallback);
    

private void FBAPIFriendsCallback(FBResult response)
    
    // (error handling here - no problem)

    // ugly code...
    var dict = Json.Deserialize(response.Text)
        as Dictionary<string,object>;
    var friendList = new List<object>();
    friendList = (List<object>)(dict["data"]);
    int _friendCount = friendList.Count;

    // ugly code...
    // (example shows getting one item, would loop through all)
    string id = getDataValueForKey(
          (Dictionary<string,object>)(friendList[0]), "id" );
    string name = getDataValueForKey(
          (Dictionary<string,object>)(friendList[0]), "name" );
    

注意非常非常丑陋的代码——用什么更优雅的方式来写这个?干杯


事实上,根据下面 swazza 的评论,这是完整的代码段落:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Parse;
using System;
using Facebook;
using System.Threading.Tasks;
using System.IO;
using System.Linq;
using Facebook.MiniJSON;


public class ParseLinkOps : MonoBehaviour
  

  ...

  public void GetFriendsFromFBThenMatch()
    
    FB.API("/me/friends", HttpMethod.GET, _cbFriends);
    // FB calls at
    // https://developers.facebook.com/docs/unity/reference/current
    

  private void _cbFriends(FBResult response)
    
    // goal: given the json result from the cloud,
    // create a List<string> containing only the FacebookID "id" numbers

    if ( ! String.IsNullOrEmpty(response.Error) )
       // .. error handling .. return; 

    var dict = Json.Deserialize(response.Text)
            as Dictionary<string,object>;

    var friendList = new List<object>();
    friendList = (List<object>)(dict["data"]);

    int _friendCount = friendList.Count;
    Debug.Log("Found friends on FB, _friendCount ... " +_friendCount);

    // so, convert that complex array of FB objects,
    // to simply an array of "id" strings
    // use very ugly code but assume someone on SO knows better later :-)

    List<string> friendIDsFromFB = new List<string>();

    for ( int k=0; k<_friendCount; ++k)
      
      string friendFBID =
        getDataValueForKey( (Dictionary<string,object>)(friendList[k]), "id");

      string friendName =
        getDataValueForKey( (Dictionary<string,object>)(friendList[k]), "name");

      Debug.Log( k +"/" +_friendCount +" " +friendFBID +" " +friendName);

      friendIDsFromFB.Add( friendFBID );
      

    // we're done, the list is in friendIDsFromFB
    StartCoroutine( _match( friendIDsFromFB ) );
    

  ...
  

【问题讨论】:

这个问题在Code Review上不是更相关吗? JW - 可能。但是 C.R. 更适合(比方说)“算法”类型的问题。这更像是一种特定类型的“如何在 Y 中做 X”类型的事情。无论如何欢呼 【参考方案1】:

使用 linq 扩展怎么样?

var dict = new Dictionary<string, object>();
var friend = dict
            .Where(s => s.Key.Equals("data"))
            .Select(s => new  Id = s.Key, Name = s.Value )
            .First();

var friendId = friend.Id;
var friendName = friend.Name;

这是一个 linq 扩展,用于迭代可枚举并对每个元素执行操作 -

public static void Execute<TSource>(this IEnumerable<TSource> source, Action<TSource> actionToExecute)

    if (source.Count() > 0)
    
        foreach (var item in source)
        
            actionToExecute(item);
        
    

编辑:所以我知道您在 Unity 游戏引擎中使用它。自从我从事 Unity 工作以来,已经有很多年了。很高兴知道他们现在支持 Linq。所以这是我编写的获取friendIds的代码。有一些特定于 ASP.Net 的代码,但 linq 部分应该可以在任何地方工作 -

// Use ASP.Net's javascript serializer to desrialize the json response received from 
// call to graph.facebook.com/me/friends
var jsSerializer = new JavaScriptSerializer();
var jsonString = " \"data\": [  \"name\": \"name1\", \"id\": \"id1\" ,  \"name\": \"name2\", \"id\": \"id2\"  ] ";

// Deserialize the json to type - Dictionary<string, object>
var dict = jsSerializer.Deserialize(jsonString, typeof(Dictionary<string, object>)) as Dictionary<string, object>;

/*Code upto here is specific to ASP.Net - At this point, be it ASP.Net or Unity, we have a dictionary that contains a key "data" which again contains a dictionaries of name value pairs*/

// The code from below is Linq and should work on Unity as well.
var friendIds = (dict["data"] as ArrayList)                     // Convert the "data" key of the dictionary into its underlying type (which is an ArrayList in this case)
                .Cast<Dictionary<string, object>>()             // ArrayList is not generic. Cast it to a generic enumerable where each element is of type Dictionary<string, object> 
               .Select(s =>
                            
                                // Each element in the cast enumerable is of type dictionary.
                                // Each dictionary has two keys - "id" and "name" that correspond to the id and name properties 
                                // of the json response received when calling graph.facebook.com/me/friends.
                                // check - https://developers.facebook.com/tools/explorer/145634995501895/?method=GET&path=me%2Ffriends&version=v2.0
                                // Because we only want Ids, fetch the value corresponding to the "id" key
                                object id = null;
                                if (s.TryGetValue("id", out id))
                                
                                    return id.ToString();
                                

                                return string.Empty;
                            );

我添加了详细的 cmets 以使该代码有点自我解释。如果您删除 cmets,它会生成简洁的代码。但是,这比普通的 for 循环性能要差。

【讨论】:

为你...youtube.com/watch?v=ACKWK55Ic9M难以置信。如此美丽。只是没想到linq,这么美。遍历所有 id 的最漂亮的方法是什么,只是一个 foreach ? :) C# 中的通用“List”方法有一个“ForEach”方法,该方法将 Func 委托作为参数并将该委托应用于列表中的每个元素。您为 IEnumerable 创建自己的 linq 扩展并使用它使您的代码看起来更具声明性 - 类似这样 - public static void Execute(this 'IEnumerable source, Action actionToExecute) if (source. Count() > 0) foreach (var item in source) actionToExecute(item); ' 然后像 enumerable.Execute(actionToPerform) 一样使用它。 我的错...我已经编辑了答案以将代码包含在上述评论中。干杯。 @swazza85 我真的很喜欢这段代码,但为什么要检查第二个代码中的 Count on source? @Measuring 你是对的——拥有一个 foreach 确实使检查计数变得多余。乔是的,就像那样,只要“MyRoutine”与“actionToExecute”委托的签名匹配。

以上是关于最好的 c# 语法/成语,从 Facebook 读取朋友数组的主要内容,如果未能解决你的问题,请参考以下文章

你所不知道的那些英语成语

C++或者C#如何读取指定内存地址的值?

如何使用 C# 从服务器端删除 facebook cookie?

使用 facebook c# sdk 在 windows phone 8 应用程序中没有从 facebook 获得登录响应

什么是最好的 OAuth2 C# 库? [关闭]

c#现在最好用的ORM是什么框架