Вот несколько различных способов сделать это. Если вы хотите придерживаться Js.Array
, как вы отметили в комментариях, вы можете сделать это следующим образом:
type point = {
x: int,
y: int,
};
let points: array(point) = [|{x: 2, y: 4}|];
let rawArray = [|[|1, 2|], [|3, 4|], [|9, 4|]|];
let append = raw => {
Array.iter(
a => {
let data: point = {x: a[0], y: a[1]};
Js.Array.push(data, points)->ignore;
},
raw,
);
};
append(rawArray);
Js.log2("new points", points);
...or with tuples with `Js.Array`
let rawTuples = [|(3, 5), (4, 9), (9, 4)|];
append(rawTuples);
Js.log2("new points", points);
[ { x: 2, y: 4 }, { x: 3, y: 5 }, { x: 4, y: 9 }, { x: 9, y: 4 } ]
Если вы хотите сделать это с помощью Array.fold_left
и Array.append
, как предложил @chenglou, вы можете попробовать это с помощью
rawArray|>Array.fold_left((a, b) =>
Array.append(a, [|{x: b[0], y: b[1]}|]), [||]);
Это может быть чище с некоторыми вспомогательными функциями, такими как:
let concatMap = f =>
Array.fold_left((a, b) => Array.append(a, f(b)), [||]);
let newPoint = coord => [|{x: coord[0], y: coord[1]}|];
Затем вызов:
let rawTuples = [|(3, 5), (4, 9), (9, 4)|];
let arrayTuples = rawTuples |> concatMap(a => [|{x: fst(a), y: snd(a)}|]);
Использование помощников также помогает мне понять, что делает каждая часть функции.
Работает и с tuples
, так как это просто массивы в ReasonML/Ocaml/Rescript.
let rawTuples = [|(3, 5), (4, 9), (9, 4)|];
let arrayTuples = rawTuples |> concatMap(a => [|{x: fst(a), y: snd(a)}|]);
У вас есть возможность создать свой массив с помощью mutable records
.
Это то, что обновляет массив изменяемых записей. Это не сильно отличается.
Здесь мы используем функцию для изменения данных в массиве.
let printCoords = coords => Array.iter(Js.log, coords);
type mutablePoint('a, 'b) = {
mutable x: 'a,
mutable y: 'b,
};
let data1: mutablePoint(int, int) = {x: 2, y: 4};
let data2: mutablePoint(int, int) = {x: 3, y: 4};
let data3: mutablePoint(int, int) = {x: 4, y: 4};
let isEven = n => {
n mod 2 == 0;
};
let multiplyByY = data => data.x = data.x * data.y;
let makeItOdd = data => data.x = data.x + 1;
let updateData = data => data.x->isEven
? data->makeItOdd : multiplyByY(data);
let points: array(mutablePoint('x, 'y)) = [|data1, data2, data3|];
let append = (fn, data) => {
Array.iter(x => {fn(x)}, data);
data;
};
points |> append(updateData);
Js.log("points after");
printCoords(points);
// points after { x: 3, y: 4 } { x: 12, y: 4 }{ x: 5, y: 4 }
Ваш вопрос касался обновления некоторых необработанных данных, поэтому вот пример того, где мы берем необработанные данные по индексу i и используем их для изменения значения x
в изменяемом массиве:
let points2: array(mutablePoint('x, 'y)) = [|data1, data2, data3|];
let printCoords = coords => Array.iter(Js.log, coords);
printCoords(points2);
let rawData = [|[|1, 2|], [|3, 4|], [|9, 4|]|];
let update_x_on_point_i = (i, x) => points2[i].x = x;
let append = raw =>
Array.iteri(
(i, d) => {
let x: int = d[0];
update_x_on_point_i(i, x);
},
raw,
);
append(rawData);
Js.log2("points2 after: ", points2);
printCoords(points2);
// points2 after: [ { x: 1, y: 4 }, { x: 3, y: 4 }, { x: 9, y: 4 } ]
Эти два массива имеют одинаковый размер, поэтому исключений нет, но легко будет один, когда длины массивов различаются, поэтому мы должны справиться с этим в реальной жизни.
Просто потому, что я сделал это сегодня по тем же причинам, которые привели меня к этому сообщению, вот версия JS Analogue
.
type point = {
x: int,
y: int,
};
let coords = [|{x: 9, y: 7}, {x: 2, y: 4}, {x: 3, y: 8}|];
Js.log("coords before");
Js.log("-------");
let append = raw =>
raw->Belt.Array.mapWithIndex(
_,
(i, r) => {
let new_point_i = {x: r[0], y: r[1]};
coords[i] = new_point_i;
},
);
let rawData = [|[|1, 2|], [|3, 4|], [|9, 4|]|];
append(rawData);
Js.log("coords after");
Js.log(coords);
coords before
[ { x: 9, y: 7 }, { x: 2, y: 4 }, { x: 3, y: 8 } ]
-------
coords after
[ { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 9, y: 4 } ]
Обновлять
Следующий код является обновленным синтаксисом для кода @yawar в сути в комментариях выше. Его объяснение стоит прочесть.
type data_item = {
symbol: string,
next: bool,
};
/* Convenience function for making data items. */
let make_data_item = (symbol, next) => {symbol, next};
let process = (data: list(data_item)) => {
/*
We track the current symbol as well as the result list in the folding function.
*/
let fold_func = ((current, result), {symbol, next}) =>
if (next) {
(symbol, [current, ...result]);
} else {
(current ++ symbol, result);
};
let (current, result) = List.fold_left(fold_func, ("", []), data);
/*
We need to reverse the result list because `[el, ...els]` above actually
builds it up in the _opposite_ order to the original input list.
*/
(current, List.rev(result));
};
let result =
process([
make_data_item("a", false),
make_data_item("b", false),
make_data_item("c", true),
make_data_item("d", false),
]);
/* result = ("cd", ["ab"]) */
person
armand
schedule
09.06.2021
coords
, так как это точная копияraw
. Просто продолжайте использовать сырье. - person Yawar   schedule 08.06.2017List.map (fun {x, y} => {x: process x, y: process y}) raw
- person Yawar   schedule 08.06.2017List.map
поможет, но области (где список был создан и где список должен быть сопоставлен) разные - person tuchk4   schedule 08.06.2017