Вы можете найти ответ на каждую отдельную операцию в отдельных вопросах, но не все изложены вместе.
1. Массив простых значений
import update from 'immutability-helper';
const oldArray = [1, 2, 3];
// add an item
const newArray = update(oldArray, {$push: [6, 7]});
// => [1, 2, 3, 6, 7]
// modify an item
const itemIndex = 1; // modify `2` value at index `1`
const newValue = 8;
const newArray = update(oldArray, { [itemIndex]: {$set: newValue} });
// => [1, 8, 3]
// remove an item
const itemIndex = 2; // delete `3` value at index `2`
const newArray = update(oldArray, {$splice: [[itemIndex, 1]] });
// => [1, 2]
2. Массив простых объектов
import update from 'immutability-helper';
const oldArray = [
{name: 'Stacey', age: 55},
{name: 'John', age: 77},
{name: 'Kim', age: 62},
];
// add an item
const newArray = update(oldArray, {$push: [
{name: 'Trevor', age: 45},
]});
// replace an item
const itemIndex = 1; // replace *John* at index `1`
const newValue = {name: 'Kevin', age: 25};
const newArray = update(oldArray, { [itemIndex]: {$set: newValue} });
// modify an item
const itemIndex = 1; // modify *John* at index `1`
const newArray = update(oldArray, {
[itemIndex]: {$merge, {
age: 85, // change John's age to 85
}}
});
// remove an item
const itemIndex = 0; // delete *Stacey* at index `0`
const newArray = update(oldArray, {$splice: [[itemIndex, 1]] } });
Вы можете использовать встроенную функцию findIndex () , чтобы найти индекс элемента на основе его свойств.
3. Массив находится в другом объекте
import update from 'immutability-helper';
const oldData = {
city: {
people: [
{name: 'Stacey', age: 55},
{name: 'John', age: 77},
{name: 'Kim', age: 62},
]
}
};
// add an item
const newArray = update(oldArray, {
city: {
people: {$push: [
{name: 'Trevor', age: 45},
]}
}
});
// replace an item
const itemIndex = 1; // replace *John* at index `1`
const newValue = {name: 'Kevin', age: 25};
const newArray = update(oldArray, {
city: {
people: {
[itemIndex]: {$set: newValue} }}
}
}
);
// modify an item
const itemIndex = 1; // modify *John* at index `1`
const newArray = update(oldArray, {
city: {
people: {
[itemIndex]: {$merge, {
age: 85, // change John's age to 85
}}
}
}
});
// remove an item
const itemIndex = 0; // delete *Stacey* at index `0`
const newArray = update(oldArray, {
city: {
people: {$splice: [[itemIndex, 1]] }
}
});
4. Объект объектов (хэши, неупорядоченные)
import update from 'immutability-helper';
const oldData = {
'hash-stacey': {name: 'Stacey', age: 55},
'hash-john': {name: 'John', age: 77},
'hash-kim': {name: 'Kim', age: 62},
};
// add an item
const newData = update(oldData, {
['hash-trevor']: {$set: {name: 'Trevor', age: 45} }
});
// replace an item at a specific hash
const itemHash = 'hash-john';
const newValue = {name: 'Kevin', age: 25};
const newData = update(oldData, { [itemHash]: {$set: newValue} });
// modify an item
const itemHash = 'hash-john';
const newData = update(oldData, {
[itemHash]: {$merge: {
age: 85, // change John's age to 85
}}
});
// remove an item
const itemHash = 'hash-stacey';
const newData = update(oldData, {$unset: [itemHash] });
Карта объектов (хэши, упорядоченные)
import update from 'immutability-helper';
const oldData = new Map([
['hash-stacey', {name: 'Stacey', age: 55}],
['hash-john', {name: 'John', age: 77}],
['hash-kim', {name: 'Kim', age: 62}],
]);
// add an item
const newData = update(oldData, {$add: [
['hash-trevor', {name: 'Trevor', age: 45}],
]});
// replace an item at a specific hash
const itemHash = 'hash-john';
const newValue = {name: 'Kevin', age: 25};
const newData = update(oldData, { [itemHash]: {$set: newValue} });
// modify an item
const itemHash = 'hash-john';
/* please edit with better single update $merge or $apply */
const newValue = update(oldData.get(itemHash), {$merge: {
age: 85, // change John's age to 85
}});
/* typescript needs to do `oldData as any` cast here */
const newData = update(oldData, { [itemHash]: {$set: newValue} });
// remove an item
const itemHash = 'hash-stacey';
const newData = update(oldData, {$remove: [itemHash] });
Как насчет этого? (Решение KISS)
void LoadCities() {
int x, y;
ifstream in("Cities.txt");
if (!in) {
cout << "Cannot open file.\n";
return;
}
for (y = 0; y < 15; y++) {
for (x = 0; x < 15; x++) {
in >> distances[x][y];
}
}
in.close();
}
Работы для меня. Не мог бы быть то, что комплекс и возможно не очень производителен, но, пока Вы не читаете 1000x1000 массив, Вы не будете видеть различия.
Вы, вероятно, хотите что-то более простое, как это:
std::vector<std::vector<std::string> > LoadCities(const std::string &filename)
{
using namespace std;
ifstream file;
file.open(filename, ios::in | ios::out);
if(!file.is_open()) {
// error
return vector<vector<double> >();
}
vector<vector<double> > data;
string line;
while(!std::getline(file, line, '\n').eof()) {
istringstream reader(line);
vector<double> lineData;
string::const_iterator i = line.begin();
while(!reader.eof()) {
double val;
reader << val;
if(reader.fail())
break;
lineData.push_back(val);
}
data.push_back(lineData);
}
return data;
}
В основном Вы используете потоки для ввода данных. Я, вероятно, делаю что-то не так (я никогда не имел дело с iostreams; P), но это должно дать Вам общее представление о том, как структурировать матричного читателя.
Это даже компилирует? Я получаю ~7 ошибок. Образец:
strtok(cities, "\n");
strtok()
первым аргументом является a char *
и не станд.:: строка.
Это помогает?
void LoadCities()
{
std::vector<double> f((std::istream_iterator<double>
(std::ifstream("city.txt"))), /* replace filename with your own */
(std::istream_iterator<double>()));
if (!f.empty()) {
std::cout << f.size() << "\n";
/* print an arbitrary data point with 2 places of decimal */
std::cout << std::setprecision(2) << f[ 0 ] << std::endl;
}
}
Работа с матрицами не означает, что у Вас должен быть многомерный массив. Особенно, с 2D массивами. Конечно, легче читать и записать ;)
Вот то, как я загрузил бы/сохранил бы его:
#include <iostream>
#include <fstream>
#include <string>
int width = 0;
int height = 0;
double **distances;
void WriteDouble( std::ofstream &stream, double toWrite )
{
char buffer[8];
memcpy( buffer, &toWrite, 8 );
stream.write( buffer, 8 );
}
void WriteInt( std::ofstream &stream, int toWrite )
{
char buffer[4];
memcpy( buffer, &toWrite, 4 );
stream.write( buffer, 4 );
}
double ReadDouble( std::ifstream &stream )
{
double d = 0;
stream.read( (char *)&d, 8 );
return d;
}
int ReadInt( std::ifstream &stream )
{
int i = 0;
stream.read( (char *)&i, 4 );
return i;
}
void Save()
{
std::ofstream stream( "cities", std::ios::out | std::ios::binary );
if( !stream.good() ) {
throw std::exception( "Error opening stream" );
}
WriteInt( stream, width );
WriteInt( stream, height );
for( int x = 0; x < width; x++ ) {
for( int y = 0; y < height; y++ ) {
WriteDouble( stream, distances[x][y] );
}
}
stream.close();
}
void Load()
{
std::ifstream stream( "cities", std::ios::in | std::ios::binary );
if( !stream.good() ) {
throw std::exception( "Error opening stream" );
}
width = ReadInt( stream );
height = ReadInt( stream );
distances = new double *[width];
for( int i = 0; i < width; i++ ) {
distances[i] = new double[height];
}
for( int x = 0; x < width; x++ ) {
for( int y = 0; y < height; y++ ) {
distances[x][y] = ReadDouble( stream );
}
}
stream.close();
}
void RunSaveTest()
{
width = 15;
height = 15;
distances = new double *[width];
for( int i = 0; i < width; i++ ) {
distances[i] = new double[height];
}
for( int x = 0; x < width; x++ ) {
for( int y = 0; y < height; y++ ) {
distances[x][y] = (double)x / (double)( y + 1 );
std::cout << distances[x][y] << std::endl;
}
}
Save();
}
void RunLoadTest()
{
Load();
for( int x = 0; x < width; x++ ) {
for( int y = 0; y < height; y++ ) {
std::cout << distances[x][y] << std::endl;
}
}
}
int main()
{
RunSaveTest();
// RunLoadTest();
return 0;
}