我有这两个数组:
$list = [
'fruit' => [],
'animals' => [],
'objects' => [],
];
$dataArray = [
'fruit' => 'apple',
'animals' => ['dog', 'cat'],
'asd' => 'bla'
];
我想合并它们,以便最后的$ list是:
[fruit] => Array
(
[0] => apple
)
[animals] => Array
(
[0] => dog
[1] => cat
)
[objects] => Array
(
)
所以,要注意的事情:
使用array_merge不起作用:
$merged = array_merge($list, $dataArray);
[fruit] => apple
[animals] => Array
(
[0] => dog
[1] => cat
)
[objects] => Array
(
)
[asd] => bla
我设法得到了我想要的东西:
foreach ($dataArray as $key => $value) {
if (isset($list[$key])) {
if (is_array($value)) {
$list[$key] = $value;
}
else {
$list[$key] = [$value];
}
}
}
但是我想知道是否有更清洁的方法来做它或其他一些我不知道的PHP功能。
答案 0 :(得分:4)
您可以通过以下几个步骤实现这一目标:
<h3>{{!item.price ?'No price':item.price}}</h3>
这将返回一个包含第一个数组中所有元素的数组,然后对第二个数组中的键进行过滤。这给你:
$result = array_intersect_key($dataArray, $list);
然后,您可以使用以下方法重新添加第一个数组中缺少的键:
Array
(
[fruit] => apple
[animals] => Array
(
[0] => dog
[1] => cat
)
)
$result + $list;
运算符和+
之间的区别在于前者不会使用第二个值覆盖第一个数组。它只会添加任何缺失的元素。
在一行中,这可以解释为:
array_merge
您可以在此处看到它:https://eval.in/865733
编辑:抱歉,完全错过了将元素保存为数组的部分。如果他们总是数组,那么你可以添加一个快速的单行代码,如:
$result = array_intersect_key($dataArray, $list) + $list;
将所有顶级元素强制转换为数组。如果您的逻辑比这更复杂,那么我不确定您是否会找到使用内置函数的方法,抱歉。
答案 1 :(得分:1)
第二条规则({em>“{。{}}($list
键中缺少的2.键)被忽略”)告诉我迭代'asd'
,而不是超过$list
。如果$dataArray
比$dataArray
大得多,那么迭代它就会浪费时间,因为它的大多数元素都会被忽略。
你的规则没有解释如何处理$list
的元素(如果它们不是空的)(我会假设它们总是数组,否则游戏会发生变化而变得过于复杂而无法提供处理它的通用代码)。
我建议的代码如下:
$list
如果将// Build the result in $result
// (you can modify $list as well if you prefer it that way)
$result = array();
// 2. keys missing from $list ('asd' key) are simply ignored
// iterate over the keys of $list, handle only the keys present in $dataArray
foreach ($list as $key => $value) {
if (array_key_exists($dataArray, $key)) {
// $key is present in $dataArray, use the value from $dataArray
$value = $dataArray[$key];
// 1. even if 'fruit' had only one element, is still an array in $list
if (! is_array($value)) {
$value = array($value);
}
}
// 3. keys with no values are still kept, even if empty
// if the key is not present in $dataArray, its value from $list is used
$result[$key] = $value;
}
块移到if (! is_array($value))
块之外,它会将if (array_key_exists())
的值转换为数组,这些值不是数组,并且与{中不存在的键相关联{1}}(例如$list
)。这样,代码运行后,$dataArray
的所有值都是数组。
您的代码也很好。除了迭代$list['objects']
而不是$result
之外,没有办法让它以更加壮观的方式更快或更容易阅读。我在这里建议的代码只是编写相同内容的另一种方式。
答案 2 :(得分:0)
我的方法将执行3个非常简单的操作:
public class TCPClient {
public static String SERVER_IP;
public static int SERVER_PORT;
private String mServerMessage; // message to send to the server
private OnMessageReceived mMessageListener = null; // sends message received notifications
private boolean mRun = false; // while this is true, the server will continue running
private PrintWriter mBufferOut; // used to send messages
public static BufferedReader mBufferIn; // used to read messages from the server
Socket socket;
public TCPClient(OnMessageReceived listener, String IP, String Port) {
mMessageListener = listener;
SERVER_IP = IP;
SERVER_PORT = Integer.parseInt(Port);
}
public void sendMessage(String message) {
if (socket == null || !socket.isConnected()) {
Log.e("313", "Socket Not Connected / Init !!!");
return;
}
if (mBufferOut != null && !mBufferOut.checkError()) {
mBufferOut.println(message);
mBufferOut.flush();
}
}
public void stopClient() {
mRun = false; //////////////////////mRun must be false///////////////////////////
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mMessageListener = null;
mBufferIn = null;
mBufferOut = null;
mServerMessage = null;
}
public void run() {
try {
// Creates a stream socket and connects it to the specified port number at the specified IP address
socket = new Socket(InetAddress.getByName(SERVER_IP), SERVER_PORT);
try {
// sends the message to the server
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
// receives the message which the server sends back
mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
mRun = true;
while (mRun) { // in this while the client listens for the messages sent by the server
mServerMessage = mBufferIn.readLine();
if (mServerMessage != null && mMessageListener != null) {
mMessageListener.messageReceived(mServerMessage); // call the method messageReceived from MyActivity class
}
}
} catch (Exception e) {} finally {
// the socket must be closed.
// It is not possible to reconnect to this socket, after it is closed,
// which means a new socket instance has to be created.
socket.close();
}
} catch (Exception e) {}
}
public interface OnMessageReceived {
public void messageReceived(String message) throws IOException;
}
public boolean isConnected() {
if (socket == null) return false;
if (socket.isConnected()) return true;
else return false;
}
}
通过引用修改$list
。&$v
中找不到匹配关键字的迭代。$dataArray
中的每个合格值强制转换为数组,并覆盖初始的空子数组。
如果合格值不是数组,它将成为生成的子数组中的唯一元素;如果是的话,那么关于子数组的任何事情都不会改变。代码:(Demo)
$dataArray
输出:
$list = [
'fruit' => [],
'animals' => [],
'objects' => []
];
$dataArray = [
'fruit' => 'apple',
'animals' => ['dog', 'cat'],
'asd' => 'bla'
];
foreach ($list as $k => &$v) {
if (isset($dataArray[$k])) {
$v = (array)$dataArray[$k];
}
}
var_export($list);
答案 3 :(得分:0)
这是两行的解决方案(但您只需将其设置为一行:))
$list = [
'fruit' => [],
'animals' => [],
'objects' => [],
];
$dataArray = [
'fruit' => 'apple',
'animals' => ['dog', 'cat'],
'asd' => 'bla'
];
$list = array_merge($list, array_intersect_key($dataArray, $list));
array_walk($list, function(&$item){$item = (array)$item;});