Skip to content

Commit abd2e9b

Browse files
joinWith kdocs
1 parent fb73426 commit abd2e9b

File tree

3 files changed

+227
-8
lines changed

3 files changed

+227
-8
lines changed

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ private interface JoinBehavior
4242
*
4343
* @include [JoinBehavior]
4444
*
45-
* See also shortcuts with each of join types:
46-
* [innerJoin], [leftJoin], [rightJoin], [fullJoin], [filterJoin], [excludeJoin].
45+
* Each join type has a corresponding shortcut function:
46+
* [innerJoin], [leftJoin], [rightJoin], [fullJoin], [filterJoin], and [excludeJoin].
47+
*
48+
* See also [joinWith], which performs a join by matching row values condition.
4749
*
4850
* @include [SelectingColumns.ColumnGroupsAndNestedColumnsMention]
4951
*
@@ -95,7 +97,7 @@ private interface SelectingColumnsJoinDsl
9597
* @include [JoinDocs]
9698
* @include [SelectingColumnsJoinDsl]
9799
* @param other [DataFrame] to join with.
98-
* @param type [JoinType] defining how rows are matched and combined.
100+
* @param type [JoinType] defining how the resulting rows are constructed.
99101
* @param selector [JoinColumnsSelector] specifying join columns;
100102
* if `null`, same-name columns are used.
101103
* @return joined [DataFrame].
@@ -123,7 +125,7 @@ private interface JoinStringApiExample
123125
* @include [JoinStringApiExample]
124126
* @param other [DataFrame] to join with.
125127
* @param columns [Column Names][String] specifying join columns.
126-
* @param type [JoinType] defining how rows are matched and combined.
128+
* @param type [JoinType] defining how the resulting rows are constructed.
127129
* @return joined [DataFrame].
128130
*/
129131
public fun <A, B> DataFrame<A>.join(
@@ -582,19 +584,19 @@ public typealias JoinColumnsSelector<A, B> = JoinDsl<A, B>.(ColumnsContainer<A>)
582584
public enum class JoinType {
583585

584586
/**
585-
* Includes all rows from the left [DataFrame]; rows with matching keys are merged,
587+
* Includes all rows from the left [DataFrame]; matching rows are merged,
586588
* unmatched right-side values are filled with `null`.
587589
*/
588590
Left,
589591

590592
/**
591-
* Includes all rows from the right [DataFrame]; rows with matching keys are merged,
593+
* Includes all rows from the right [DataFrame]; matching rows are merged,
592594
* unmatched left-side values are filled with `null`.
593595
*/
594596
Right,
595597

596598
/**
597-
* Includes only rows with matching keys from both [DataFrame]s;
599+
* Includes only matching rows from both [DataFrame]s;
598600
* rows are merged.
599601
*/
600602
Inner,

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt

Lines changed: 215 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,96 @@ import org.jetbrains.kotlinx.dataframe.DataRow
55
import org.jetbrains.kotlinx.dataframe.Selector
66
import org.jetbrains.kotlinx.dataframe.annotations.Interpretable
77
import org.jetbrains.kotlinx.dataframe.annotations.Refine
8+
import org.jetbrains.kotlinx.dataframe.documentation.DocumentationUrls
9+
import org.jetbrains.kotlinx.dataframe.documentation.DocumentationUrls.Join
10+
import org.jetbrains.kotlinx.dataframe.documentation.ExcludeFromSources
11+
import org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns
12+
import org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns.ColumnGroupsAndNestedColumnsMention
813
import org.jetbrains.kotlinx.dataframe.impl.api.joinWithImpl
914

15+
/**
16+
* A [JoinExpression] defines the matching condition between [rows][DataRow] of the two [DataFrame]s.
17+
* It provides access to row values from both the left and right [DataFrame]s
18+
* and expects a [Boolean] result indicating whether the rows match.
19+
* All combinations of rows from the left and right [DataFrame]s that satisfies
20+
* this condition are matched.
21+
*
22+
* This method is useful when the data was not originally designed relationally, or when
23+
* rows should be matched based on custom logic rather than simple equality.
24+
*
25+
* Creates a new [DataFrame] by combining [rows][DataRow]
26+
* from both inputs according to the [\joinExpression] matching rule.
27+
*/
28+
@ExcludeFromSources
29+
private interface JoinWithCommonDescription
30+
31+
// `joinWith` method used in the example
32+
private interface JoinWithMethod
33+
34+
/**
35+
* ### Examples
36+
* ```kotlin
37+
* // Join rows where the `fullName` value in the left DataFrame
38+
* // contains the `firstName` value in the right DataFrame.
39+
* dfLeft.{@get [JoinWithMethod] joinWith}(dfRight) { left -> left.fullName.contains(right.firstName) }
40+
*
41+
* // Join rows where the `date` value in the right DataFrame
42+
* // falls within the interval defined by the `startDate` and `endDate`
43+
* // values in the left DataFrame.
44+
* dfLeft.{@get [JoinWithMethod] joinWith}(dfRight) { right.date in startDate..endDate }
45+
* ```
46+
*/
47+
private interface JoinWithExample
48+
49+
/**
50+
* A specialized [DataRow] used in a [JoinExpression].
51+
*
52+
* Represents a row from the left [DataFrame] (as the receiver)
53+
* and provides access to the row from the right [DataFrame] via [right].
54+
*/
1055
public interface JoinedDataRow<out A, out B> : DataRow<A> {
1156
public val right: DataRow<B>
1257
}
1358

59+
/**
60+
* A special [row][DataRow] expression used to define
61+
* the row-matching condition in a [joinWith] operation.
62+
*
63+
* Provides the [row][DataRow] of the left [DataFrame] both
64+
* as the receiver (`this`) and as the argument (`it`),
65+
* allowing you to reference its values directly.
66+
*
67+
* The [row][DataRow] of the right [DataFrame] is available
68+
* via [right][JoinedDataRow.right].
69+
*
70+
* The expression must return a [Boolean] indicating whether
71+
* the rows from the left and right [DataFrame]s match.
72+
*/
1473
public typealias JoinExpression<A, B> = Selector<JoinedDataRow<A, B>, Boolean>
1574

75+
/**
76+
* Joins this [DataFrame] with the [right][\right] [DataFrame]
77+
* using the provided [\joinExpression].
78+
*
79+
* @include [JoinWithCommonDescription]
80+
*
81+
* {@include [JoinTypeDescription]}
82+
*
83+
* Each join type has a corresponding shortcut function:
84+
* [innerJoinWith], [leftJoinWith], [rightJoinWith], [fullJoinWith], [filterJoinWith], and [excludeJoinWith].
85+
*
86+
* See also [join], which performs a join by simply matching columns.
87+
*
88+
* @include [SelectingColumns.ColumnGroupsAndNestedColumnsMention]
89+
*
90+
* For more information, {@include [DocumentationUrls.JoinWith]}.
91+
*
92+
* @include [JoinWithExample]
93+
* @param [right] [DataFrame] to join with.
94+
* @param [type] [JoinType] defining how rows are matched and combined.
95+
* @param [joinExpression] [JoinExpression] specifying rows join condition.
96+
* @return joined [DataFrame].
97+
*/
1698
@Refine
1799
@Interpretable("JoinWith")
18100
public fun <A, B> DataFrame<A>.joinWith(
@@ -21,31 +103,163 @@ public fun <A, B> DataFrame<A>.joinWith(
21103
joinExpression: JoinExpression<A, B>,
22104
): DataFrame<A> = joinWithImpl(right, type, addNewColumns = type.addNewColumns, joinExpression)
23105

106+
/**
107+
* Performs [inner join][JoinType.Inner] of this [DataFrame] with the [right][\right] [DataFrame]
108+
* using the provided [\joinExpression]. {@include [JoinType.Inner]}
109+
*
110+
* This is a shortcut for [joinWith] with [JoinType.Inner].
111+
*
112+
* @include [JoinWithCommonDescription]
113+
*
114+
* See also general [joinWith] as well as other shortcuts with each of join types:
115+
* [leftJoinWith], [rightJoinWith], [fullJoinWith], [filterJoinWith], [excludeJoinWith].
116+
*
117+
* See also [join], which performs a join by simply matching columns.
118+
*
119+
* @include [SelectingColumns.ColumnGroupsAndNestedColumnsMention]
120+
*
121+
* For more information, {@include [DocumentationUrls.JoinWith]}.
122+
*
123+
* @include [JoinWithExample] {@set [JoinWithMethod] innerJoinWith}
124+
* @param [right] [DataFrame] to join with.
125+
* @param [joinExpression] [JoinExpression] specifying rows join condition.
126+
* @return joined [DataFrame].
127+
*/
24128
@Refine
25129
@Interpretable("InnerJoinWith")
26130
public fun <A, B> DataFrame<A>.innerJoinWith(right: DataFrame<B>, joinExpression: JoinExpression<A, B>): DataFrame<A> =
27131
joinWith(right, JoinType.Inner, joinExpression)
28132

133+
/**
134+
* Performs [left join][JoinType.Left] of this [DataFrame] with the [right][\right] [DataFrame]
135+
* using the provided [\joinExpression]. {@include [JoinType.Left]}
136+
*
137+
* This is a shortcut for [joinWith] with [JoinType.Left].
138+
*
139+
* @include [JoinWithCommonDescription]
140+
*
141+
* See also general [joinWith] as well as other shortcuts with each of join types:
142+
* [innerJoinWith], [rightJoinWith], [fullJoinWith], [filterJoinWith], [excludeJoinWith].
143+
*
144+
* See also [join], which performs a join by simply matching columns.
145+
*
146+
* @include [SelectingColumns.ColumnGroupsAndNestedColumnsMention]
147+
*
148+
* For more information, {@include [DocumentationUrls.JoinWith]}.
149+
*
150+
* @include [JoinWithExample] {@set [JoinWithMethod] leftJoinWith}
151+
* @param [right] [DataFrame] to join with.
152+
* @param [joinExpression] [JoinExpression] specifying rows join condition.
153+
* @return joined [DataFrame].
154+
*/
29155
@Refine
30156
@Interpretable("LeftJoinWith")
31157
public fun <A, B> DataFrame<A>.leftJoinWith(right: DataFrame<B>, joinExpression: JoinExpression<A, B>): DataFrame<A> =
32158
joinWith(right, JoinType.Left, joinExpression)
33159

160+
/**
161+
* Performs [right join][JoinType.Right] of this [DataFrame] with the [right][\right] [DataFrame]
162+
* using the provided [\joinExpression]. {@include [JoinType.Right]}
163+
*
164+
* This is a shortcut for [joinWith] with [JoinType.Right].
165+
*
166+
* @include [JoinWithCommonDescription]
167+
*
168+
* See also general [joinWith] as well as other shortcuts with each of join types:
169+
* [innerJoinWith], [leftJoinWith], [fullJoinWith], [filterJoinWith], [excludeJoinWith].
170+
*
171+
* See also [join], which performs a join by simply matching columns.
172+
*
173+
* @include [SelectingColumns.ColumnGroupsAndNestedColumnsMention]
174+
*
175+
* For more information, {@include [DocumentationUrls.JoinWith]}.
176+
*
177+
* @include [JoinWithExample] {@set [JoinWithMethod] rightJoinWith}
178+
* @param [right] [DataFrame] to join with.
179+
* @param [joinExpression] [JoinExpression] specifying rows join condition.
180+
* @return joined [DataFrame].
181+
*/
34182
@Refine
35183
@Interpretable("RightJoinWith")
36184
public fun <A, B> DataFrame<A>.rightJoinWith(right: DataFrame<B>, joinExpression: JoinExpression<A, B>): DataFrame<A> =
37185
joinWith(right, JoinType.Right, joinExpression)
38186

187+
/**
188+
* Performs [full join][JoinType.Full] of this [DataFrame] with the [right][\right] [DataFrame]
189+
* using the provided [\joinExpression]. {@include [JoinType.Full]}
190+
*
191+
* This is a shortcut for [joinWith] with [JoinType.Full].
192+
*
193+
* @include [JoinWithCommonDescription]
194+
*
195+
* See also general [joinWith] as well as other shortcuts with each of join types:
196+
* [leftJoinWith], [rightJoinWith], [innerJoinWith], [filterJoinWith], [excludeJoinWith].
197+
*
198+
* See also [join], which performs a join by simply matching columns.
199+
*
200+
* @include [SelectingColumns.ColumnGroupsAndNestedColumnsMention]
201+
*
202+
* For more information, {@include [DocumentationUrls.JoinWith]}.
203+
*
204+
* @include [JoinWithExample] {@set [JoinWithMethod] fullJoinWith}
205+
* @param [right] [DataFrame] to join with.
206+
* @param [joinExpression] [JoinExpression] specifying rows join condition.
207+
* @return joined [DataFrame].
208+
*/
39209
@Refine
40210
@Interpretable("FullJoinWith")
41211
public fun <A, B> DataFrame<A>.fullJoinWith(right: DataFrame<B>, joinExpression: JoinExpression<A, B>): DataFrame<A> =
42212
joinWith(right, JoinType.Full, joinExpression)
43213

214+
/**
215+
* Performs [filter join][JoinType.Filter] of this [DataFrame] with the [right][\right] [DataFrame]
216+
* using the provided [\joinExpression]. {@include [JoinType.Filter]}
217+
*
218+
* This is a shortcut for [joinWith] with [JoinType.Filter].
219+
*
220+
* @include [JoinWithCommonDescription]
221+
*
222+
* See also general [joinWith] as well as other shortcuts with each of join types:
223+
* [leftJoinWith], [rightJoinWith], [fullJoinWith], [innerJoinWith], [excludeJoinWith].
224+
*
225+
* See also [join], which performs a join by simply matching columns.
226+
*
227+
* @include [SelectingColumns.ColumnGroupsAndNestedColumnsMention]
228+
*
229+
* For more information, {@include [DocumentationUrls.JoinWith]}.
230+
*
231+
* @include [JoinWithExample] {@set [JoinWithMethod] filterJoinWith}
232+
* @param [right] [DataFrame] to join with.
233+
* @param [joinExpression] [JoinExpression] specifying rows join condition.
234+
* @return joined [DataFrame].
235+
*/
44236
@Refine
45237
@Interpretable("FilterJoinWith")
46238
public fun <A, B> DataFrame<A>.filterJoinWith(right: DataFrame<B>, joinExpression: JoinExpression<A, B>): DataFrame<A> =
47-
joinWithImpl(right, JoinType.Inner, addNewColumns = false, joinExpression)
239+
joinWithImpl(right, JoinType.Filter, addNewColumns = false, joinExpression)
48240

241+
/**
242+
* Performs [exclude join][JoinType.Exclude] of this [DataFrame] with the [right][\right] [DataFrame]
243+
* using the provided [\joinExpression]. {@include [JoinType.Exclude]}
244+
*
245+
* This is a shortcut for [joinWith] with [JoinType.Exclude].
246+
*
247+
* @include [JoinWithCommonDescription]
248+
*
249+
* See also general [joinWith] as well as other shortcuts with each of join types:
250+
* [leftJoinWith], [rightJoinWith], [fullJoinWith], [filterJoinWith], [innerJoinWith].
251+
*
252+
* See also [join], which performs a join by simply matching columns.
253+
*
254+
* @include [SelectingColumns.ColumnGroupsAndNestedColumnsMention]
255+
*
256+
* For more information, {@include [DocumentationUrls.JoinWith]}.
257+
*
258+
* @include [JoinWithExample] {@set [JoinWithMethod] excludeJoinWith}
259+
* @param [right] [DataFrame] to join with.
260+
* @param [joinExpression] [JoinExpression] specifying rows join condition.
261+
* @return joined [DataFrame].
262+
*/
49263
@Refine
50264
@Interpretable("ExcludeJoinWith")
51265
public fun <A, B> DataFrame<A>.excludeJoinWith(

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,7 @@ internal interface DocumentationUrls {
182182

183183
/** [See `join` on the documentation website.]({@include [Url]}/join.html) */
184184
interface Join
185+
186+
/** [See `joinWith` on the documentation website.]({@include [Url]}/joinWith.html) */
187+
interface JoinWith
185188
}

0 commit comments

Comments
 (0)