我像这个
脚本
var data = JSON.parse(request.responseText, function(key, x) {
if (key === "flavor_profiles") {
x = x.split(',');
return x;
}
return x;
});
一样解决了它。jshtml
<ul class="tags">
{{#each flavor_profiles}}
<li><a href="#" class="tag">{{this}}</a></li>
{{/each}}
</ul>
我想这是意见问题和权衡。
我赞成没有在表定义中定义的检查并在应用程序级别上执行的检查,以避免重复逻辑并提高可维护性(CF单个责任原则)。
对于字段有效性的内容,例如一个数字在范围内左右,我倾向于将这些数字定位在应用程序本身中,因为DB通常无法以精度验证它们(如何确保字符串是有效的电子邮件例如),并且在应用程序中使用所有检查也有助于构建一致的错误消息。
OTOH,DB是您唯一可以检查某些不变性的地方,例如某些列的Unicity,外国/主密钥关系的一致性,交易隔离,原子质...在并发和分布式设置中尤其如此:数据库是系统中唯一一致的部分,因此“知道足够”可以进行一些检查。
另外,数据库所能完成的所有工作都是您不必重新实现应用程序的逻辑,并且DB的代码通常经常进行测试=&gt;您可以选择将大量委派给数据库,以保持应用程序代码精益。
有人说,您不应过多地依赖DB的特定特定功能,并通过某些抽象界面将其从应用程序中脱离式功能,尽管我经常不同意:供应商特定的DB功能(例如示例中的特定检查)通常是该数据库所在的大部分添加值,而在20年的软件工程中,我几乎从未遇到过神话般的情况,在这种情况下,一个项目决定将其DB供应商交换为另一个(或他们做到了,他们确实从某些特定功能中受益=&gt;
简而言之:
- 确保在整体上仅在一个地方定义每个逻辑,
- 让您的数据库尽其所能,并尝试使您的代码很大一部分从事业务增值功能,而不是技术性的东西,
- 这都是一种贸易 -真的,只要选择一种哲学,就接受它的侧面:)
问题是拼字图投影和视图空间坐标:
gluortho2d(0,w,h,0);
在此投影中,左上坐标为(0,0),右下是(w
,h
),因此中心为(w/2)
,h/2
),取决于视图的大小。由于对象的坐标没有更改,因此它不再在场景的中心中,因为对象的坐标仍然是旧中心(old_w/2
,old_h/code old_h/2
)。
使用中心为(0,0)的投影:
gluOrtho2D(-w/2, w/2, h/2, -h/2);
当然,现在您需要为场景中的对象指定不同的坐标。例如(0,0)中心。
如果您想保持场景,则需要保留投影。只需更改视口(glviewport(0,0,W,H)
),但不要更改投影(删除gluortho2d(0,w,w,h,0)
) 。
我只是添加答案,因为我还不能写任何评论,尽管我在CSS上并不陌生...
是的,您可以使用Flexbox,但我也会添加CSS网格,因为两者的组合都可以给您如果您打算制作更大的图表……
一旦使其正常工作,则更加灵活性,它很容易使用...
复制并将此代码粘贴到代码编辑器中并将其显示在您的浏览器中。
(如果使用VSCODE,则可以使用Liveserver扩展名)
,然后转到浏览器内部的开发工具(Ctrl+Shift+i),然后单击图标选择一个元素(在非常左侧的顶部)。
然后,在第一个Div内,您将看到带有网格单词的标签,单击它,然后在屏幕上看到网格。
最后,您只需要像那些旧战舰游戏之一或2D笛卡尔坐标系统一样填充行和列。
请记住,将物品放在网格上时,最好使用行而不是行和列的区域,因为这样更容易理解。
例如,在这种情况下,Connector 1从垂直线9到垂直线10,或第一个图填充第5行和第9行之间的空间,依此类推。
希望它有帮助!
顺便说一句,我更改了颜色,因为说明更容易。HTML
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Document</title>
</head>
<body>
<!-- GRID FLOWCHART -->
<div class="flowchart">
<!-- FIRST FIGURE -->
<div class="set" id="set1">
<div class="box"><p>alpha</p></div>
</div>
<!-- FIRST CONNECTOR -->
<div class="connector" id="connector1"></div>
<!-- SECOND FIGURE -->
<div class="set" id="set2">
<div class="box"><p>beta</p></div>
<div class="box"><p>gamma</p></div>
<div class="box"><p>delta</p></div>
</div>
<!-- SECOND CONNECTOR -->
<div class="connector" id="connector2"></div>
<!-- THIRD FIGURE -->
<div class="set" id="set3">
<div class="box"><p>gamma</p></div>
</div>
</div>
</body>
</html>
CSS:
body {
width: 100vw;
height: 100vh;
background-color: #d3d3d3;
}
/* ****** GENERIC SHAPES : ********** */
.flowchart {
display: grid;
grid-template-columns: repeat(24, 1fr);
grid-template-rows: repeat(12, 1fr);
width: fit-content;
height: fit-content;
grid-gap: 2px;
}
.set {
min-width: 100px;
min-height: 100px;
border: 2px dashed blue;
border-radius: 15px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box {
width: 80%;
height: 15%;
background-color: rgb(255, 255, 255);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 4%;
padding: 6%;
border: 1px solid black;
/* border-radius: 5px; */
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 0.9em;
}
.connector {
width: 120%;
max-height: 3px;
background-color: black;
transform: translateX(-6%);
}
/* ************* FIGURES : ************* */
#set1 {
grid-column: 5/9;
grid-row: 5/12;
}
#set2 {
grid-column: 10/14;
grid-row: 5/12;
}
#set3 {
grid-column:15/19;
grid-row: 5/12;
}
/* ******** CONNECTORS : *********** */
#connector1 {
grid-column: 9/10;
grid-row: 8/9;
}
#connector2 {
grid-column: 14/15;
grid-row: 8/9;
}
我设法自己弄清楚了。
这是我为外面的任何人提供的Exec-Maven-plug + JIB CLI解决方案。
要测试粘贴,请将其调整到您的环境中,然后运行MVN Clean Package -P Local
。
此pom.xml
来自多模块设置,因此您可能必须重构或省略&lt; parent&gt;&gt;&gt;/parent&gt;
标签以适合您需要。
它的作用:
- 清洁目标目录
- 将您的源文件编译到目标目录
- 中的目标目录中的类中
- ,重新包装类,libs,libs, 爆炸式 form form(用于更好的层缓存)正确地进入Spring Boot的非标准
boot-inf
输出目录 docker build
,docker push
通过引擎盖下方穿过jib cli- 在结尾处执行
docker pull
(出于调试目的),
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>redacted</artifactId>
<groupId>com.redacted</groupId>
<version>0.0.1</version>
</parent>
<artifactId>sm-test</artifactId>
<version>0.0.1</version>
<name>test</name>
<description>test</description>
<packaging>jar</packaging>
<properties>
<profile.name>default</profile.name>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<mainClass>com.redacted.smtest.SmTestApplication</mainClass>
<java.server.user>0:0</java.server.user>
<java.to.image.tag>ghcr.io/redacted/${project.artifactId}:${project.version}-${profile.name}</java.to.image.tag>
<java.from.image.tag>openjdk:11.0.14-jre@sha256:e2e90ec68d3eee5a526603a3160de353a178c80b05926f83d2f77db1d3440826</java.from.image.tag>
<java.from.classpath>../target/${project.name}/${profile.name}/${project.build.finalName}.jar</java.from.classpath>
</properties>
<profiles>
<!-- local -->
<profile>
<id>local</id>
<properties>
<profile.name>local</profile.name>
</properties>
<activation>
<property>
<name>noTest</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>jib jar</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>jib</executable>
<workingDirectory>.</workingDirectory>
<skip>false</skip>
<arguments>
<argument>jar</argument>
<argument>--mode=exploded</argument>
<argument>--target=${java.to.image.tag}</argument>
<argument>--from=${java.from.image.tag}</argument>
<argument>--user=${java.server.user}</argument>
<argument>--creation-time=${maven.build.timestamp}</argument>
<argument>--jvm-flags=-Xms32m,-Xmx128m,-Dspring.profiles.active=default</argument>
<argument>${java.from.classpath}</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>docker pull</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>docker</executable>
<workingDirectory>.</workingDirectory>
<skip>false</skip>
<arguments>
<argument>pull</argument>
<argument>${java.to.image.tag}</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.yworks</groupId>
<artifactId>yguard</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.name}</finalName>
<directory>../target/${project.name}/${profile.name}/</directory>
<outputDirectory>../target/${project.name}/${profile.name}/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>obfuscate</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<skip>false</skip>
<tasks>
<property name="runtime_classpath" refid="maven.runtime.classpath"/>
<!--suppress UnresolvedMavenProperty -->
<taskdef name="yguard" classname="com.yworks.yguard.YGuardTask" classpath="${runtime_classpath}"/>
<mkdir dir="${project.build.directory}/obfuscated"/>
<yguard>
<inoutpair in="${project.build.directory}/classes"
out="${project.build.directory}/obfuscated"/>
<externalclasses>
<!--suppress UnresolvedMavenProperty -->
<pathelement path="${runtime_classpath}"/>
</externalclasses>
<rename mainclass="${mainClass}"
logfile="${project.build.directory}/rename.log.xml"
scramble="true"
replaceClassNameStrings="true">
<property name="error-checking" value="pedantic"/>
<property name="naming-scheme" value="best"/>
<property name="language-conformity" value="compatible"/>
<property name="overload-enabled" value="true"/>
<!-- Generated by sm-test -->
<map>
<class map="d1e6064d$5a15$449b$a632$b2d967a61021" name="com.redacted.smtest.YGuardMappingRunner"/>
</map>
</rename>
</yguard>
<delete dir="${project.build.directory}/classes/com"/>
<copy todir="${project.build.directory}/classes/com/" overwrite="true">
<fileset dir="${project.build.directory}/obfuscated/com/" includes="**"/>
</copy>
<delete dir="${project.build.directory}/obfuscated"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${mainClass}</mainClass>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
cosciate jib.yaml
jib> jib cli
的文件
apiVersion: jib/v1alpha1
kind: BuildFile
workingDirectory: "/app"
entrypoint: ["java","-cp","/app/resources:/app/classes:/app/libs/*"]
layers:
entries:
- name: classes
files:
- properties:
filePermissions: 755
src: /classes
dest: /app/classes
这是一个 必须编写一个小的抛出类来为Yguard的唯一类和软件包名称生成自定义映射(显然它无法自行完成):
package com.redacted.smtest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.UUID;
@Slf4j
@Component
public class YGuardMappingRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
if (args == null || args.length == 0)
return;
generateYGuardMapping(Path.of(args[0]));
}
void generateYGuardMapping(Path path) throws IOException {
var packageSb = new StringBuilder();
var classSb = new StringBuilder();
mapPackages(path, packageSb);
mapClasses(path, classSb);
if (packageSb.length() > 0 && classSb.length() > 0)
log.info(
"\n<!-- Generated by sm-test -->\n<map>\n{}\n{}</map>",
packageSb.toString(),
classSb.toString());
else if (packageSb.length() > 0 && classSb.length() == 0)
log.info("\n<!-- Generated by sm-test -->\n<map>\n{}</map>", packageSb.toString());
else if (packageSb.length() == 0 && classSb.length() > 0)
log.info("\n<!-- Generated by sm-test -->\n<map>\n{}</map>", classSb.toString());
}
private void mapClasses(Path path, StringBuilder classSb) throws IOException {
try (var stream = Files.walk(path, Integer.MAX_VALUE)) {
stream
.distinct()
.filter(o -> o.getNameCount() >= 12)
.filter(Files::isRegularFile)
.map(o -> o.subpath(8, o.getNameCount()))
.map(o -> o.toString().replace("\\", ".").replace(".java", ""))
.filter(o -> !o.contains("Sm"))
.sorted()
.forEach(
o ->
classSb.append(
String.format("%2s<class map=\"%s\" name=\"%s\"/>%n", "", getRandStr(), o)));
}
}
private void mapPackages(Path path, StringBuilder packageSb) throws IOException {
try (var stream = Files.walk(path, Integer.MAX_VALUE)) {
stream
.map(Path::getParent)
.distinct()
.filter(o -> o.getNameCount() >= 12)
.map(o -> o.subpath(8, o.getNameCount()))
.map(o -> o.toString().replace("\\", "."))
.sorted()
.forEach(
o ->
packageSb.append(
String.format(
"%2s<package map=\"%s\" name=\"%s\"/>%n", "", getRandStr(), o)));
}
}
private String getRandStr() {
return UUID.randomUUID().toString().replaceAll("[-]+", "\\$");
}
}
您没有使用数组,因此所有以前的输入将被最后一个输入所取代。如果您没有更多的字段可随着请求发送,则可以通过将表格放入循环中来解决此问题。 按钮
标签还接受一个值,因此您可以跳过隐藏的输入字段以使用较少的代码。
@foreach($features as $feature)
<tr>
<td>{{ $feature->detail }}</td>
<td>row</td>
<td>
<form action="{{route('sendDate')}}" method="post" >
@csrf
<button type="submit" name="ft" value="{{ $feature->detail }}" > insert</button>
</form>
</td>
</tr>
@endforeach
我认为您选择的日期数据类型是int,这就是为什么您会遇到错误,即INT不是DateTime的子类型
DateTime? selectedDay = DateTime.now();
//Here is Calendar widget
Calendar(
initialDate: selectedDay,
events: const {},
startOnMonday: true,
isExpandable: true,
eventDoneColor: Colors.green,
selectedColor: Colors.pink,
todayColor: Colors.blue,
eventColor: Colors.grey,
onDateSelected: (date) {
_handleNewDate(date);
},
),
void _handleNewDate(date) {
setState(() {
selectedDay = date;
// selectedEvent = events[selectedDay] ?? [];
print(selectedDay);
});
}
如果您喜欢IFS,则可能需要这样调整(也应该以类似的方式使用HH:MM)
=IFS(G3<6;"Night Off Prime";G3<18;"Day Off Prime";G3<23;"Prime";TRUE;"Night Off Prime")
:设置)
另外:
=IFS(G3<0;"#N/A";G3<6;"Night Off Prime";G3<18;"Day Off Prime";G3<23;"Prime";G3<24;"Night Off Prime";TRUE;"#N/A")
该行为是由于默认参数shuffle = true
in model.fit(*)
而不是错误。根据 docs >::
布尔值(是在每个时期之前将训练数据洗净)还是str(用于“批次”)。当x是tf.data.dataset的生成器或对象时,该参数将被忽略。 “批次”是处理HDF5数据局限性的特殊选择;它在批处理大小的块中散发。当steps_per_epoch不是一个时,没有效果。
因此,当传递tf.data.dataset
时,此参数将被忽略,并且在每个时期之后,数据不会像其他数组中的其他方法一样重新封装。
这是获得两种方法相同结果的代码:
import numpy as np
import tensorflow as tf
tf.keras.utils.set_random_seed(0)
n_examples, n_dims = (100, 10)
raw_dataset = np.random.randn(n_examples, n_dims)
model = tf.keras.models.Sequential(
[
tf.keras.layers.Dense(
1024, activation="relu", use_bias=True
),
tf.keras.layers.Dense(
1, activation="linear", use_bias=True
),
]
)
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss="mse",
)
x_train = raw_dataset[:, :-1]
y_train = raw_dataset[:, -1]
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
n_epochs = 10
batch_size = 16
use_dataset = False
if use_dataset:
model.fit(
dataset.batch(batch_size=batch_size),
epochs=n_epochs,
)
else:
model.fit(
x=x_train,
y=y_train,
batch_size=batch_size,
shuffle=False,
epochs=n_epochs,
)
print("Evaluation:")
model.evaluate(x_train, y_train)
model.evaluate(dataset.batch(batch_size=batch_size))
。
我认为说特定实现的实用方法是“正确的方式™”,如果它仅是“正确”(“正确”),而“正确”的解决方案与“错误”解决方案相反 Tomáš的解决方案是对基于字符串的数组比较的明显改进,但这并不意味着它客观地“正确”。什么是正确?是最快的吗?它是最灵活的吗?是最简单的理解吗?调试是最快的吗?它使用最少的操作吗?它有任何副作用吗?没有一个解决方案可以拥有最好的一切。
托马斯(Tomáš)可以说他的解决方案很快,但我也想说这是不必要的复杂。它试图是一种适用于所有阵列的多合一解决方案。实际上,它甚至不仅接受数组作为输入,而且仍然试图给出一个“有效”的答案。
仿制药提供可重复性,
我的答案将以不同的方式解决问题。我将从一个通用arraycompare
过程开始,该过程仅与踏上数组有关。从那里,我们将构建其他基本比较功能,例如arrayequal
和arraydeepequal
等,
// arrayCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayCompare = f => ([x,...xs]) => ([y,...ys]) =>
x === undefined && y === undefined
? true
: Boolean (f (x) (y)) && arrayCompare (f) (xs) (ys)
我认为最好的代码甚至不需要注释,这是也不例外。这里很少发生,您几乎没有努力就可以理解此过程的行为。当然,现在有些ES6语法对您来说似乎很陌生,但这仅仅是因为ES6相对较新。
正如类型所建议的那样,arraycompare
采用比较函数,f
,两个输入数组,xs
和ys
。在大多数情况下,我们要做的就是为输入数组中的每个元素调用f(x)(y)
。如果用户定义f
返回false> false
- 感谢&amp;&amp;&amp;
',我们返回早期false
false 。短路评估。因此,是的,这意味着比较器可以尽早停止迭代,并在不需要的情况下阻止循环通过其余的输入阵列。
接下来,严格的比较
,使用我们的arraycompare
函数,我们可以轻松创建可能需要的其他功能。我们将从基本array equal
开始……
// equal :: a -> a -> Bool
const equal = x => y =>
x === y // notice: triple equal
// arrayEqual :: [a] -> [a] -> Bool
const arrayEqual =
arrayCompare (equal)
const xs = [1,2,3]
const ys = [1,2,3]
console.log (arrayEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2) && (3 === 3) //=> true
const zs = ['1','2','3']
console.log (arrayEqual (xs) (zs)) //=> false
// (1 === '1') //=> false
很简单。 arrayequal
可以使用arraycompare
和一个比较a
与b
使用===的比较器函数进行定义。
(严格平等)。
请注意,我们还将等于
定义为其自己的功能。这突出了arraycompare
作为高阶功能的作用,可以在另一种数据类型(array)的上下文中使用我们的一阶比较器。
松散的比较,
我们可以使用==
而不是很容易地定义arrayloose equal
。现在,当比较1
(编号)与'1'
(string)时,结果将为true
…
// looseEqual :: a -> a -> Bool
const looseEqual = x => y =>
x == y // notice: double equal
// arrayLooseEqual :: [a] -> [a] -> Bool
const arrayLooseEqual =
arrayCompare (looseEqual)
const xs = [1,2,3]
const ys = ['1','2','3']
console.log (arrayLooseEqual (xs) (ys)) //=> true
// (1 == '1') && (2 == '2') && (3 == '3') //=> true
深层比较(递归
)可能注意到这只是比较。当然,Tomáš的解决方案是“正确的Way™”,因为它确实具有深入的比较,对吗?
好吧,我们的arraycompare
过程的用途足够多,可以使深度平等测试变得轻而易举……
// isArray :: a -> Bool
const isArray =
Array.isArray
// arrayDeepCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayDeepCompare = f =>
arrayCompare (a => b =>
isArray (a) && isArray (b)
? arrayDeepCompare (f) (a) (b)
: f (a) (b))
const xs = [1,[2,[3]]]
const ys = [1,[2,['3']]]
console.log (arrayDeepCompare (equal) (xs) (ys)) //=> false
// (1 === 1) && (2 === 2) && (3 === '3') //=> false
console.log (arrayDeepCompare (looseEqual) (xs) (ys)) //=> true
// (1 == 1) && (2 == 2) && (3 == '3') //=> true
简单。我们使用 的高阶函数构建一个深层比较器。这次,我们使用自定义比较器包装arraycompare
,该比较器将检查a
和b
是数组。如果是这样,请重新申请arrayDeepCompare
否则将A
和b
与用户指定的比较器(f
)进行比较。这使我们能够将深层比较行为与实际比较单个元素进行比较分开。即,如上所述,我们可以使用等于
, loode> soce> 或我们进行的任何其他比较器进行深入比较。
因为ArrayDeepCompare
是咖喱的,所以我们可以像以前的示例中一样部分地应用它
// arrayDeepEqual :: [a] -> [a] -> Bool
const arrayDeepEqual =
arrayDeepCompare (equal)
// arrayDeepLooseEqual :: [a] -> [a] -> Bool
const arrayDeepLooseEqual =
arrayDeepCompare (looseEqual)
,这已经对Tomáš的解决方案有了明显的改进或根据需要对我的阵列进行深入比较。
对象比较(示例)
现在,如果您有一系列对象或其他东西怎么办? 也许您要将这些数组视为“相等”
// idEqual :: {id: Number} -> {id: Number} -> Bool
const idEqual = x => y =>
x.id !== undefined && x.id === y.id
// arrayIdEqual :: [a] -> [a] -> Bool
const arrayIdEqual =
arrayCompare (idEqual)
const xs = [{id:1}, {id:2}]
const ys = [{id:1}, {id:2}]
console.log (arrayIdEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2) //=> true
const zs = [{id:1}, {id:6}]
console.log (arrayIdEqual (xs) (zs)) //=> false
// (1 === 1) && (2 === 6) //=> false
如果每个对象都具有相同的id
值…简单, 。在这里,我使用了香草JS对象,但是这种类型的比较器可以适用于任何任何对象类型。甚至您的自定义对象。 Tomáš的解决方案是否需要完全重新设计,以支持具有对象的这种平等测试
深度测试?没问题。我们构建了高度通用的通用功能,因此它们将在各种用例中工作。
const xs = [{id:1}, [{id:2}]]
const ys = [{id:1}, [{id:2}]]
console.log (arrayCompare (idEqual) (xs) (ys)) //=> false
console.log (arrayDeepCompare (idEqual) (xs) (ys)) //=> true
任意比较(例如)
,或者如果您想进行其他类型的完全任意的比较怎么办?也许我想知道每个x
是否大于每个y
……
// gt :: Number -> Number -> Bool
const gt = x => y =>
x > y
// arrayGt :: [a] -> [a] -> Bool
const arrayGt = arrayCompare (gt)
const xs = [5,10,20]
const ys = [2,4,8]
console.log (arrayGt (xs) (ys)) //=> true
// (5 > 2) && (10 > 4) && (20 > 8) //=> true
const zs = [6,12,24]
console.log (arrayGt (xs) (zs)) //=> false
// (5 > 6) //=> false
更少的是
您可以看到我们实际上使用更少的代码做更多的事情。 arraycompare
本身以及我们制作的每个自定义比较器都有一个非常简单的实现。
轻松地,我们可以准确地定义我们希望如何比较两个阵列 - 浅,深,严格,松散,某些对象属性或某些任意计算,或使用一个过程 - - >,<代码> arraycompare 。也许甚至梦想着regexp
比较器!我知道孩子们如何爱那些言论……
这是最快的吗?没有。但这可能也不需要。如果速度是用于衡量代码质量的唯一度量,那么许多非常出色的代码就会被抛弃 - 这就是为什么我将这种方法称为实用方法。也许要更公平, a 实用的方式。此描述适合此答案,因为我并不是说这个答案与其他答案相比仅是实际的。客观上是正确的。我们的实用性很高,几乎没有易于推理的代码。没有其他代码可以说我们没有赢得此描述。
这是否使您成为您的“正确”解决方案?这是您的决定。没有其他人可以为您做到这一点;只有你知道自己的需求。在几乎所有情况下,我都将直接,实用和多才多艺的代码重视而不是聪明和快速的代码。您的价值可能会有所不同,因此请选择对您有用的东西。
编辑
我的旧答案更专注于将arrayequal
分解为微小的过程。这是一个有趣的练习,但实际上并不是解决此问题的最佳(最实用)方法。如果您有兴趣,可以看到此修订历史记录。
如果您只有2个参数可提取,则wide_to_long
将起作用。
在这里,您有3个,因此您可以使用多个索引进行手动重塑:
regex = r'alumn_(\d+)_subject_(\d+)_(.*)'
out = (df
.set_index(['id', 'classroom', 'city'])
.pipe(lambda d: d.set_axis(pd.MultiIndex
.from_frame(d.columns.str.extract(regex),
names=['alumn', 'subject', None]
),
axis=1))
.stack(['alumn', 'subject'])
.reset_index()
)
输出:
Empty DataFrame
Columns: [id, classroom, city, alumn, subject, mark, name, teacher]
Index: []
输出单行(df.loc [0] = range = range(df.shape [1])
):
id classroom city alumn subject mark name teacher
0 0 1 2 0 0 3 203 403
1 0 1 2 0 1 4 204 404
2 0 1 2 0 2 5 205 405
3 0 1 2 0 3 6 206 406
4 0 1 2 0 4 7 207 407
.. .. ... ... ... ... ... ... ...
195 0 1 2 9 5 98 298 498
196 0 1 2 9 6 99 299 499
197 0 1 2 9 7 100 300 500
198 0 1 2 9 8 101 301 501
199 0 1 2 9 9 102 302 502
[200 rows x 8 columns]
使用
filter
选择列,然后使用重命名
将“组”字符串替换为“预期销售”:输出:
Use
filter
to select your columns then userename
to replace "Group" string by "Expected Sales":Output:
熊猫:如何在多个列上执行相同的计算,这来自传递列表?