【问题标题】:How do I merge two arrays by comparing only specific keys?如何通过仅比较特定键来合并两个数组?
【发布时间】:2013-09-26 06:28:40
【问题描述】:

所以我有两个数组 - $twitterData 和 $facebookData。

$twitterData 看起来像

[0] => Array
    (
        [text] => Hello World http://somelink
        [type] => twitter
    )

[1] => Array
    (
        [text] => We like to keep our developers happy! 
        [type] => twitter
    )

$facebookData 看起来像

[0] => Array
        (
            [text] => We like to keep our developers happy! http://somelink.com
            [type] => facebook
        )

[1] => Array
        (
            [text] => Take a look
            [type] => facebook
        )

我正在尝试将这两个数组合并到一个名为 $socialFeed 的数组中。问题是我试图以这种方式合并它们,所以假设“文本”键的前 50 个字符对于任何两个数组项都相同,那么我将合并数组只让该项显示一次。因此,“我们想让我们的开发人员满意!http://somelink.com”会出现一次(而不是一个有链接,一个没有链接)。

我尝试过同时使用 array_diff 和 array_intersect,但它们都比较键的整个值,而不仅仅是文本键的前 X 个字符。

【问题讨论】:

  • 您希望目标数组具有什么结构?你指出你的源数组
  • 结果应该是什么?
  • 你在你的问题中给出了答案。创建两个仅包含文本的前 X 个字符的派生数组,然后对它们进行比较。这些派生数组之间的差异路由与原始数组的差异路由相同
  • 你必须自己动手。 PHP 的数组函数很方便,并且擅长它们的工作,但它们不是通用的玩具。如果您只想比较数组元素的子集,那么您将不得不提供自己的自定义工具。
  • @b_dubb:目标/结果数组应该与上面发布的数组具有相同的结构。唯一的区别是,如果一个项目同时存在于这两种类型中,则类型将是“两者”

标签: php arrays data-structures merge array-merge


【解决方案1】:

使用你想要共有的值作为数组键,如果条目已经存在,则推送网络:

$feedResult = array();

foreach ($twitterPost AS $entry){
    $newKey = substr($entry["text"], 0 , 10); //first 10chars
    if (isset($feedResult[$newKey])){
       //actually this will never happen, because when iterating the FIRST
       //post array, there will be no entry. But doing so allows to swap arround
       //the processing order of networks.
       $feedResult[$newKey]["network"][] = "twitter"; //add another network
    }else{
       //create new entry
       $feedResult[$newKey] = array("network" => array("twitter"), "text" => $entry["text"]);
    }
}

foreach ($facebookPost AS $entry){
    $newKey = substr($entry["text"], 0 , 10); //first 10chars
    if (isset($feedResult[$newKey])){
       $feedResult[$newKey]["network"][] = "facebook"; //add another network
    }else{
       //create new entry
       $feedResult[$newKey] = array("network" => array("facebook"), "text" => $entry["text"]);
    }
}

最后你会得到类似的东西(它未经测试,但想法应该很清楚):

["Hello Worl"] => Array
(
  ["Text"] = "Hello World http://somelink"
  ["network"] => Array
  ( 
       [0] => "twitter" 
  )
)
["We like to"] => Array
(
  ["Text"] = "We like to keep our developers happy!"
  ["network"] => Array
  ( 
     [0] => "twitter",
     [1] => "facebook" 
  )
)
["Take a loo"] => Array
(
  ["Text"] = "Take a look"
  ["network"] => Array
  ( 
     [0] => "facebook" 
  )
)

优化是使用 COMPLETE 文本的 md5() 哈希作为新键。然后它们被合并,当文本值相等时 - (或哈希冲突,但那是另一个主题,很可能不会发生在新闻帖子中)

【讨论】:

    【解决方案2】:

    我继续为你准备了一堂课。基本上我遍历两个数组并创建一个仅包含两个数组中的文本数据的新数组。创建新数组后(检查具有相同文本的现有数组数据 - 没有重复),我为每个原始数组设置布尔变量,然后循环遍历唯一文本字符串数组并检查每个数组中的文本字符串。如果我在原始数组之一中找到文本,我会更改相应原始数组的布尔值。我测试两个布尔变量的值并相应地设置新的 $socialArr 值。希望这是有道理的。代码已经过测试并且可以工作。

    <?php
    
    class socialArray {
    
        public function init($twitter,$facebook){
            $this->combinedText = $this->combinedTextArr($twitter,$facebook);
            $this->socialArr = $this->makeSocialArr($twitter,$facebook);
            return $this->socialArr;
        }
    
        public function combinedTextArr($twitter,$facebook){
            $combinedText = array();
            foreach($twitter as $key => $value){
                if( !in_array($value["text"],$combinedText ) ){
                    $combinedText[] = $value["text"];
                }
            }
            foreach($facebook as $key => $value){
                if( !in_array($value["text"],$combinedText ) ){
                    $combinedText[] = $value["text"];
                }
            }
            return $combinedText;
        }
    
        public function makeSocialArr($twitter,$facebook){
            $socialArr = array();
            foreach($this->combinedText as $value){
                $twitterTest = false;
                $facebookTest = false;
                foreach($twitter as $var){
                    if( $var["text"] == $value) {
                        $twitterTest = true;
                    }
                }
                foreach($facebook as $var){
                    if( $var["text"] == $value ) {
                        $facebookTest = true;
                    }
                }
                if( $twitterTest === true && $facebookTest === false ) {
                    $socialArr[] = array(
                                            'text' => $value,
                                            'type' => 'twitter'
                                        );
                } else if ( $twitterTest === false && $facebookTest === true ) {
                    $socialArr[] = array(
                                            'text' => $value,
                                            'type' => 'facebook'
                                        );
                } else if ( $twitterTest === true && $facebookTest === true ) {
                    $socialArr[] = array(
                                            'text' => $value,
                                            'type' => 'both'
                                        );
                }
            }
            return $socialArr;
        }
    
    }
    
    
    $facebook = array();
    
    $facebook[] = array(
                        "text" => "A post on facebook with text and stuff",
                        "type" => "facebook"
                    );
    
    $facebook[] = array(
                        "text" => "This occurs in both arrays",
                        "type" => "facebook"
                    );
    
    $twitter = array();
    
    $twitter[] = array(
                        "text" => "A tweet of the utmost importance",
                        "type" => "twitter"
                    );
    
    $twitter[] = array(
                        "text" => "This occurs in both arrays",
                        "type" => "twitter"
                    );
    
    $socArrMaker = new socialArray();
    $socialArr = $socArrMaker->init($twitter,$facebook);
    
    echo "<html><head><style type=\"text/css\">body{ font-family: sans-serif; }</style></head><body><pre>\r\n";
    print_r($socialArr);
    echo "</pre></body></html>\r\n";
    

    产生...

    Array
    (
        [0] => Array
            (
                [text] => A tweet of the utmost importance
                [type] => twitter
            )
    
        [1] => Array
            (
                [text] => This occurs in both arrays
                [type] => both
            )
    
        [2] => Array
            (
                [text] => A post on facebook with text and stuff
                [type] => facebook
            )
    
    )
    

    【讨论】:

    • @raeq 对此进行了测试,它似乎可以满足您的要求
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 2020-04-21
    相关资源
    最近更新 更多